diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml new file mode 100644 index 00000000..a6ed62c6 --- /dev/null +++ b/.github/workflows/benchmarks.yml @@ -0,0 +1,55 @@ +name: Googlebenchmark +on: [push, pull_request] +#on: +# push: +# branches: +# - main + +jobs: + benchmark: + name: Performance regression check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Install boost + id: install-boost + run: | + bash .github/workflows/scripts/install_boost.sh + echo "BOOST_ROOT=${{runner.workspace}}/Loki/boost_1_84_0" >> "$GITHUB_OUTPUT" + + - name: Configure CMake + run: cmake -DENABLE_BENCHMARKING:BOOL=TRUE -S $GITHUB_WORKSPACE -B ${{runner.workspace}}/build + env: + BOOST_ROOT: ${{ steps.install-boost.outputs.BOOST_ROOT }} + + - name: Build + working-directory: ${{runner.workspace}}/build + run: export CXXFLAGS="-Werror" && cmake --build . + + # Run benchmark and store the output to a file + - name: Run benchmark + run: ${{runner.workspace}}/build/benchmarks/persistent_factory --benchmark_format=json | tee benchmark_result.json + # Download previous benchmark result from cache (if exists) + - name: Download previous benchmark data + uses: actions/cache@v1 + with: + path: ./cache/benchmarks/ + key: ${{ runner.os }}-benchmark + # Run `github-action-benchmark` action + - name: Store benchmark result + uses: benchmark-action/github-action-benchmark@v1 + with: + # What benchmark tool the output.txt came from + tool: 'googlecpp' + # Where the output from the benchmark tool is stored + output-file-path: benchmark_result.json + # Where the previous data file is stored + external-data-json-path: ./benchmarks/cache/benchmark-data.json + # Workflow will fail when an alert happens + fail-on-alert: true + # GitHub API token to make a commit comment + github-token: ${{ secrets.GITHUB_TOKEN }} + # Enable alert commit comment + comment-on-alert: true + # Upload the updated cache file for the next job by actions/cache diff --git a/.github/workflows/scripts/install_boost.sh b/.github/workflows/scripts/install_boost.sh new file mode 100644 index 00000000..673eba41 --- /dev/null +++ b/.github/workflows/scripts/install_boost.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +wget --no-check-certificate 'https://archives.boost.io/release/1.84.0/source/boost_1_84_0.tar.gz' +tar xf boost_1_84_0.tar.gz + +## We use header-only parts + +#cd boost_1_84_0 +#./bootstrap.sh + +# Compile with fPIC flag +#export CXXFLAGS="-fPIC" +#./b2 cxxflags="$CXXFLAGS" link=static diff --git a/.github/workflows/unittests.yml b/.github/workflows/unittests.yml new file mode 100644 index 00000000..aa0dddf3 --- /dev/null +++ b/.github/workflows/unittests.yml @@ -0,0 +1,34 @@ +name: Googletest Unit Tests + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + + defaults: + run: + shell: bash + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Download boost + id: install-boost + run: | + bash .github/workflows/scripts/install_boost.sh + echo "BOOST_ROOT=${{runner.workspace}}/Loki/boost_1_84_0" >> "$GITHUB_OUTPUT" + + - name: Configure CMake + run: cmake -DENABLE_TESTING:BOOL=TRUE -S $GITHUB_WORKSPACE -B ${{runner.workspace}}/build + env: + BOOST_ROOT: ${{ steps.install-boost.outputs.BOOST_ROOT }} + + - name: Build + working-directory: ${{runner.workspace}}/build + run: export CXXFLAGS="-Werror" && cmake --build . + + - name: Test + working-directory: ${{runner.workspace}}/build/tests + run: GTEST_OUTPUT=xml:test-results/ GTEST_COLOR=1 ctest -V diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..b2fd9a72 --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +# Build artefacts +build + +# IDE files +.vscode + +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..37249c0e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,89 @@ +cmake_minimum_required(VERSION 3.13) + +############################################################## +# Language setup +############################################################## + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +############################################################## +# Establish project +############################################################## + +project(sketches VERSION 0.1 LANGUAGES C CXX) + +# Compilation flags, some configuration-specific +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wextra -pedantic -fPIC") +set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -fomit-frame-pointer") +set(CMAKE_CXX_FLAGS_DEBUG "-O3 -DDEBUG") + +# Set a default build type if none was specified +set(default_build_type "Debug") +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to '${default_build_type}', as none was specified.") + set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE + STRING "Choose the type of build." FORCE) +endif() + +option(ENABLE_TESTING "Enables compilation of tests." OFF) +if (ENABLE_TESTING) + message("Building tests enabled.") +else() + message("Building tests disabled.") +endif() + +############################################################## +# CMake modules and macro files +############################################################## + +# make cache variables for install destinations +include(GNUInstallDirs) + +list(APPEND CMAKE_MODULE_PATH + "${PROJECT_SOURCE_DIR}/cmake" +) +include("configure_boost") +include("configure_ccache") + +# CCache +configure_ccache() + +# Boost +configure_boost() +find_package(Boost ${BOOST_MIN_VERSION}) +include_directories(${Boost_INCLUDE_DIRS}) +#include_directories("${PROJECT_SOURCE_DIR}/external/flatbuffers/include") + + +############################################################## +# Add library and executable targets +############################################################## + +# Add FlatBuffers directly to our build. This defines the `flatbuffers` target. +#set(FLATBUFFERS_MAX_PARSING_DEPTH 16) +#set(FLATBUFFERS_SRC_DIR "${PROJECT_SOURCE_DIR}/external/flatbuffers/") +#add_subdirectory(${FLATBUFFERS_SRC_DIR} +# ${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-build +# EXCLUDE_FROM_ALL) + +add_subdirectory(src) + +add_subdirectory(exe) + +add_subdirectory(examples) + +set(ENABLE_TESTING True) +if (ENABLE_TESTING) + add_subdirectory(tests) +endif() + +set(ENABLE_BENCHMARKING True) +if (ENABLE_BENCHMARKING) + add_subdirectory(benchmarks) +endif() + +########### +# Install # +########### diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..f288702d --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/README.md b/README.md new file mode 100644 index 00000000..b7f5b462 --- /dev/null +++ b/README.md @@ -0,0 +1,92 @@ +# Loki + +ATTENTION: Loki's testing framework must be stronger, and Loki itself must still be tested in production. Therefore, we strongly advise against using it already. However, we are thankful for all kinds of feedback, suggestions, and feature requests. + +Loki is a C++17 library for efficient syntactic and semantic parsing of PDDL files. Loki implements exhaustive error handling to provide meaningful clang-style messages for syntactic, semantic, and modeling errors. The resulting PDDL objects are structurally uniquely constructed immutable pointer objects stored in persistent and continuous memory to enable hashing in constant time, equality comparison in constant time, and cache-efficient data access. + +## Supported PDDL Requirements + +- [x] :strips +- [x] :typing +- [x] :negative-preconditions +- [x] :disjunctive-preconditions +- [x] :equality +- [x] :existential-preconditions +- [x] :universal-preconditions +- [x] :quantified-preconditions +- [x] :conditional-effects +- [ ] :fluents +- [x] :numeric-fluents +- [ ] :object-fluents +- [x] :adl +- [ ] :durative-actions +- [ ] :derived-predicates +- [ ] :timed-initial-literals +- [ ] :preferences +- [ ] :constraints +- [x] :action-costs + + +## Dependencies + +Loki depends on a fraction of Boost's (boost.org) header-only libraries. + +- Fusion +- Spirit x3 +- Container + + +## Installation + +```console +cmake -S . -B build +cmake --build build -j16 +``` + +## Running the Examples + +The examples illustrate best practices on how to use Loki. + +The first example shows the incorrect handling of the ownership semantics. The example is supposed to crash when trying to print the domain for the second time. + +```console +./build/examples/undefined_behavior +``` + +The second example shows how to parse a domain and problem file which is supposed to be used in a planning system where a non-fragmented indexing of atoms and literals is preferred. + +```console +./build/examples/single_problem +``` + +The third example shows how to detect structurally equivalent problems over a common domain. + +```console +./build/examples/multiple_problems +``` + +The fourth example shows how to find the matched positions of each PDDL object in the input stream and how to report customized clang-style error reports. + +```console +./build/examples/position_cache +``` + + +## Running the Executables + +Parsing a domain file and printing it. + +```console +./build/exe/domain benchmarks/gripper/domain.pddl +``` + +Parsing a domain and a problem file and printing both. + +```console +./build/exe/problem benchmarks/gripper/domain.pddl benchmarks/gripper/p-2-0.pddl +``` + + +## Acknowledgements + +This work was partially supported by the Wallenberg AI, Autonomous Systems and Software Program (WASP) funded by the Knut and Alice Wallenberg Foundation. diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt new file mode 100644 index 00000000..793f03c9 --- /dev/null +++ b/benchmarks/CMakeLists.txt @@ -0,0 +1,15 @@ +include(FetchContent) + +FetchContent_Declare( + googlebenchmark + GIT_REPOSITORY https://github.com/google/benchmark.git + GIT_TAG v1.8.3 +) + +# Make Google Benchmark available +FetchContent_MakeAvailable(googlebenchmark) + +# Now declare your executable +add_executable(persistent_factory "persistent_factory.cpp") +target_link_libraries(persistent_factory parsers) +target_link_libraries(persistent_factory benchmark::benchmark) \ No newline at end of file diff --git a/benchmarks/cache/benchmark-data.json b/benchmarks/cache/benchmark-data.json new file mode 100644 index 00000000..e69de29b diff --git a/benchmarks/persistent_factory.cpp b/benchmarks/persistent_factory.cpp new file mode 100644 index 00000000..5b1b4fab --- /dev/null +++ b/benchmarks/persistent_factory.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../include/loki/common/pddl/types.hpp" +#include "../include/loki/common/memory.hpp" + +#include + +#include +#include +#include + + +/// @brief In this benchmark, we evaluate the performance of constructing atoms. +static void BM_ConstructAtoms(benchmark::State& state) { + const size_t num_objects = 100; + const size_t num_predicates = 100; + + for (auto _ : state) { + // Create num_objects-many objects with name object_1,...,object_ + auto object_factory = loki::ObjectFactory(); + auto objects = loki::pddl::ObjectList(); + for (size_t i = 1; i <= num_objects; ++i) { + objects.push_back(object_factory.get_or_create( + ("object_" + std::to_string(i))) + ); + } + + // Create num_predicates-many binary predicates with name predicate_1,...,predicate_ + auto predicate_factory = loki::PredicateFactory(); + auto parameter_factory = loki::ParameterFactory(); + auto variable_factory = loki::VariableFactory(); + auto parameters = loki::pddl::ParameterList{ + parameter_factory.get_or_create( + variable_factory.get_or_create("?variable_left"), + loki::pddl::TypeList{}), + parameter_factory.get_or_create( + variable_factory.get_or_create("?variable_right"), + loki::pddl::TypeList{}) + }; + + auto predicates = loki::pddl::PredicateList(); + for (size_t i = 1; i <= num_predicates; ++i) { + predicates.push_back(predicate_factory.get_or_create( + ("predicate_" + std::to_string(i)), + parameters)); + } + + auto atom_factory = loki::AtomFactory(); + auto term_factory = loki::TermFactory(); + auto atoms = loki::pddl::AtomList(); + // Construct num_objects^2 * num_predicates many atoms + for (const auto& predicate : predicates) { + for (const auto& object_left : objects) { + for (const auto& object_right : objects) { + atoms.push_back(atom_factory.get_or_create( + predicate, + loki::pddl::TermList{ + term_factory.get_or_create(object_left), + term_factory.get_or_create(object_right) + })); + } + } + } + } +} +BENCHMARK(BM_ConstructAtoms); + +BENCHMARK_MAIN(); diff --git a/cmake/configure_boost.cmake b/cmake/configure_boost.cmake new file mode 100644 index 00000000..ac1a8849 --- /dev/null +++ b/cmake/configure_boost.cmake @@ -0,0 +1,12 @@ + +macro(configure_boost) + set(Boost_USE_STATIC_LIBS ON) + set(Boost_USE_MULTITHREADED ON) + set(Boost_USE_STATIC_RUNTIME OFF) + set(BOOST_MIN_VERSION "1.74.0") + + if (DEFINED ENV{BOOST_ROOT}) + set(Boost_NO_SYSTEM_PATHS ON) + set(BOOST_ROOT $ENV{BOOST_ROOT}) + endif() +endmacro() diff --git a/cmake/configure_ccache.cmake b/cmake/configure_ccache.cmake new file mode 100644 index 00000000..c13ad3a4 --- /dev/null +++ b/cmake/configure_ccache.cmake @@ -0,0 +1,11 @@ + +macro(configure_ccache) + # If it's available, use ccache to cache compilation results. The two ccache options + # allow sharing compilation results between different build directories. + find_program(CCACHE_FOUND ccache) + if(CCACHE_FOUND AND NOT WIN32) # Windows Github Actions find "ccache" --> ignore it. + message("Using ccache") + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE + "CCACHE_BASEDIR=${CMAKE_CURRENT_SOURCE_DIR} CCACHE_NOHASHDIR=true ccache") + endif(CCACHE_FOUND AND NOT WIN32) +endmacro() diff --git a/data/gripper/domain.pddl b/data/gripper/domain.pddl new file mode 100644 index 00000000..36b293cd --- /dev/null +++ b/data/gripper/domain.pddl @@ -0,0 +1,36 @@ +(define (domain gripper-strips) + (:requirements :strips) + (:constants rooma roomb) + (:predicates (room ?r) + (ball ?b) + (gripper ?g) + (at-robby ?r) + (at ?b ?r) + (free ?g) + (carry ?o ?g)) + + (:action move + :parameters (?from ?to) + :precondition (and (room ?from) (room ?to) (at-robby ?from)) + :effect (and (at-robby ?to) + (not (at-robby ?from)))) + + + + (:action pick + :parameters (?obj ?room ?gripper) + :precondition (and (ball ?obj) (room ?room) (gripper ?gripper) + (at ?obj ?room) (at-robby ?room) (free ?gripper)) + :effect (and (carry ?obj ?gripper) + (not (at ?obj ?room)) + (not (free ?gripper)))) + + + (:action drop + :parameters (?obj ?room ?gripper) + :precondition (and (ball ?obj) (room ?room) (gripper ?gripper) + (carry ?obj ?gripper) (at-robby ?room)) + :effect (and (at ?obj ?room) + (free ?gripper) + (not (carry ?obj ?gripper))))) + diff --git a/data/gripper/p-2-0.pddl b/data/gripper/p-2-0.pddl new file mode 100644 index 00000000..16120633 --- /dev/null +++ b/data/gripper/p-2-0.pddl @@ -0,0 +1,28 @@ + + + +(define (problem gripper-2) +(:domain gripper-strips) +(:objects left right ball1 ball2) +(:init +(room rooma) +(room roomb) +(gripper left) +(gripper right) +(ball ball1) +(ball ball2) +(free left) +(free right) +(at ball1 rooma) +(at ball2 rooma) +(at-robby rooma) +) +(:goal +(and +(at ball1 roomb) +(at ball2 roomb) +) +) +) + + diff --git a/data/gripper/p-2-1.pddl b/data/gripper/p-2-1.pddl new file mode 100644 index 00000000..6d599c39 --- /dev/null +++ b/data/gripper/p-2-1.pddl @@ -0,0 +1,28 @@ + + + +(define (problem gripper-2) +(:domain gripper-strips) +(:objects ball1 ball2 left right) +(:init +(room rooma) +(room roomb) +(gripper left) +(gripper right) +(ball ball1) +(ball ball2) +(free left) +(free right) +(at ball1 rooma) +(at ball2 rooma) +(at-robby rooma) +) +(:goal +(and +(at ball1 roomb) +(at ball2 roomb) +) +) +) + + diff --git a/data/miconic/domain.pddl b/data/miconic/domain.pddl new file mode 100644 index 00000000..e7d9aa4e --- /dev/null +++ b/data/miconic/domain.pddl @@ -0,0 +1,58 @@ +(define (domain miconic) + (:requirements :strips :typing ) + (:types passenger - object + floor - object + ) + +(:predicates +(origin ?person - passenger ?floor - floor) +;; entry of ?person is ?floor +;; inertia + +(destin ?person - passenger ?floor - floor) +;; exit of ?person is ?floor +;; inertia + +(above ?floor1 - floor ?floor2 - floor) +;; ?floor2 is located above of ?floor1 + +(boarded ?person - passenger) +;; true if ?person has boarded the lift + +(served ?person - passenger) +;; true if ?person has alighted as her destination + +(lift-at ?floor - floor) +;; current position of the lift is at ?floor +) + + +;;stop and allow boarding + +(:action board + :parameters (?f - floor ?p - passenger) + :precondition (and (lift-at ?f) (origin ?p ?f)) + :effect (and (boarded ?p) (not (origin ?p ?f)))) + +(:action depart + :parameters (?f - floor ?p - passenger) + :precondition (and (lift-at ?f) (destin ?p ?f) + (boarded ?p)) + :effect (and (not (boarded ?p)) + (served ?p))) +;;drive up + +(:action up + :parameters (?f1 - floor ?f2 - floor) + :precondition (and (lift-at ?f1) (above ?f1 ?f2)) + :effect (and (lift-at ?f2) (not (lift-at ?f1)))) + + +;;drive down + +(:action down + :parameters (?f1 - floor ?f2 - floor) + :precondition (and (lift-at ?f1) (above ?f2 ?f1)) + :effect (and (lift-at ?f2) (not (lift-at ?f1)))) +) + diff --git a/data/miconic/p02.pddl b/data/miconic/p02.pddl new file mode 100644 index 00000000..4a79b55b --- /dev/null +++ b/data/miconic/p02.pddl @@ -0,0 +1,229 @@ + + + +(define (problem mixed-f14-p23-u0-v0-d0-a0-n0-A0-B0-N0-F0) + (:domain miconic) + (:requirements :typing) + (:objects p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 + p10 p11 p12 p13 p14 p15 p16 p17 p18 p19 + p20 p21 p22 - passenger + f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 + f10 f11 f12 f13 - floor) + + +(:init +(above f0 f1) +(above f0 f2) +(above f0 f3) +(above f0 f4) +(above f0 f5) +(above f0 f6) +(above f0 f7) +(above f0 f8) +(above f0 f9) +(above f0 f10) +(above f0 f11) +(above f0 f12) +(above f0 f13) + +(above f1 f2) +(above f1 f3) +(above f1 f4) +(above f1 f5) +(above f1 f6) +(above f1 f7) +(above f1 f8) +(above f1 f9) +(above f1 f10) +(above f1 f11) +(above f1 f12) +(above f1 f13) + +(above f2 f3) +(above f2 f4) +(above f2 f5) +(above f2 f6) +(above f2 f7) +(above f2 f8) +(above f2 f9) +(above f2 f10) +(above f2 f11) +(above f2 f12) +(above f2 f13) + +(above f3 f4) +(above f3 f5) +(above f3 f6) +(above f3 f7) +(above f3 f8) +(above f3 f9) +(above f3 f10) +(above f3 f11) +(above f3 f12) +(above f3 f13) + +(above f4 f5) +(above f4 f6) +(above f4 f7) +(above f4 f8) +(above f4 f9) +(above f4 f10) +(above f4 f11) +(above f4 f12) +(above f4 f13) + +(above f5 f6) +(above f5 f7) +(above f5 f8) +(above f5 f9) +(above f5 f10) +(above f5 f11) +(above f5 f12) +(above f5 f13) + +(above f6 f7) +(above f6 f8) +(above f6 f9) +(above f6 f10) +(above f6 f11) +(above f6 f12) +(above f6 f13) + +(above f7 f8) +(above f7 f9) +(above f7 f10) +(above f7 f11) +(above f7 f12) +(above f7 f13) + +(above f8 f9) +(above f8 f10) +(above f8 f11) +(above f8 f12) +(above f8 f13) + +(above f9 f10) +(above f9 f11) +(above f9 f12) +(above f9 f13) + +(above f10 f11) +(above f10 f12) +(above f10 f13) + +(above f11 f12) +(above f11 f13) + +(above f12 f13) + + + +(origin p0 f0) +(destin p0 f1) + +(origin p1 f10) +(destin p1 f6) + +(origin p2 f2) +(destin p2 f1) + +(origin p3 f8) +(destin p3 f7) + +(origin p4 f3) +(destin p4 f2) + +(origin p5 f12) +(destin p5 f2) + +(origin p6 f12) +(destin p6 f5) + +(origin p7 f4) +(destin p7 f12) + +(origin p8 f8) +(destin p8 f1) + +(origin p9 f2) +(destin p9 f6) + +(origin p10 f8) +(destin p10 f4) + +(origin p11 f9) +(destin p11 f13) + +(origin p12 f2) +(destin p12 f0) + +(origin p13 f12) +(destin p13 f8) + +(origin p14 f2) +(destin p14 f9) + +(origin p15 f1) +(destin p15 f2) + +(origin p16 f10) +(destin p16 f12) + +(origin p17 f6) +(destin p17 f12) + +(origin p18 f13) +(destin p18 f1) + +(origin p19 f3) +(destin p19 f1) + +(origin p20 f1) +(destin p20 f3) + +(origin p21 f13) +(destin p21 f4) + +(origin p22 f7) +(destin p22 f10) + + + + + + +(lift-at f0) +) + + +(:goal + + +(and +(served p0) +(served p1) +(served p2) +(served p3) +(served p4) +(served p5) +(served p6) +(served p7) +(served p8) +(served p9) +(served p10) +(served p11) +(served p12) +(served p13) +(served p14) +(served p15) +(served p16) +(served p17) +(served p18) +(served p19) +(served p20) +(served p21) +(served p22) +)) +) + + diff --git a/data/schedule/domain.pddl b/data/schedule/domain.pddl new file mode 100644 index 00000000..91bcb2aa --- /dev/null +++ b/data/schedule/domain.pddl @@ -0,0 +1,207 @@ + + +(define (domain schedule) + (:requirements :adl :typing) + (:types temperature-type + ashape + surface + machine + part + colour + width + anorient) + + (:constants cold hot - temperature-type + cylindrical - ashape + polisher roller lathe grinder punch drill-press + spray-painter immersion-painter - machine + polished rough smooth - surface) + + (:predicates (temperature ?obj - part ?temp - temperature-type) + (busy ?machine - machine) + (scheduled ?obj - part) + (objscheduled) + (surface-condition ?obj - part ?surface-cond - surface) + (shape ?obj - part ?shape - ashape) + (painted ?obj - part ?colour - colour) + (has-hole ?obj - part ?width - width ?orientation - anorient) + (has-bit ?machine - machine ?width - width) + (can-orient ?machine - machine ?orientation - anorient) + (has-paint ?machine - machine ?colour - colour)) + + (:action do-polish + :parameters (?x - part) + :precondition (and (not (busy polisher)) + (not (scheduled ?x)) + (temperature ?x cold)) + :effect (and (busy polisher) + (scheduled ?x) + (surface-condition ?x polished) + (when (not (objscheduled)) + (objscheduled)) + (forall (?oldsurface - surface) + (when (and (surface-condition ?x ?oldsurface) + (not (= ?oldsurface polished))) + (not (surface-condition ?x ?oldsurface)))))) + + (:action do-roll + :parameters (?x - part) + :precondition (and (not (busy roller)) + (not (scheduled ?x))) + :effect (and + (busy roller) + (scheduled ?x) + (temperature ?x hot) + (shape ?x cylindrical) + (when (not (objscheduled)) + (objscheduled)) + (forall (?oldsurface - surface) + (when (surface-condition ?x ?oldsurface) + (not (surface-condition ?x ?oldsurface)))) + (forall (?oldpaint - colour) + (when (painted ?x ?oldpaint) + (not (painted ?x ?oldpaint)))) + (forall (?oldwidth - width ?oldorient - anorient) + (when (has-hole ?x ?oldwidth ?oldorient) + (not (has-hole ?x ?oldwidth ?oldorient)))) + (forall (?oldshape - ashape) + (when (and (shape ?x ?oldshape) + (not (= ?oldshape cylindrical))) + (not (shape ?x ?oldshape)))) + (forall (?oldtemp - temperature-type) + (when (and (temperature ?x ?oldtemp) + (not (= ?oldtemp hot))) + (not (temperature ?x ?oldtemp)))))) + + (:action do-lathe + :parameters (?x - part) + :precondition (and (not (busy lathe)) + (not (scheduled ?x))) + :effect (and + (busy lathe) + (scheduled ?x) + (surface-condition ?x rough) + (shape ?x cylindrical) + (when (not (objscheduled)) + (objscheduled)) + (forall (?oldshape - ashape) + (when (and (shape ?x ?oldshape) + (not (= ?oldshape cylindrical))) + (not (shape ?x ?oldshape)))) + (forall (?oldsurface - surface) + (when (and (surface-condition ?x ?oldsurface) + (not (= ?oldsurface rough))) + (not (surface-condition ?x ?oldsurface)))) + (forall (?oldpaint - colour) + (when (painted ?x ?oldpaint) + (not (painted ?x ?oldpaint)))))) + + (:action do-grind + :parameters (?x - part) + :precondition (and (not (busy grinder)) + (not (scheduled ?x))) + :effect (and + (busy grinder) + (scheduled ?x) + (surface-condition ?x smooth) + (when (not (objscheduled)) + (objscheduled)) + (forall (?oldsurface - surface) + (when (and (surface-condition ?x ?oldsurface) + (not (= ?oldsurface smooth))) + (not (surface-condition ?x ?oldsurface)))) + (forall (?oldpaint - colour) + (when (painted ?x ?oldpaint) + (not (painted ?x ?oldpaint)))))) + + (:action do-punch + :parameters (?x - part ?width - width ?orient - anorient) + :precondition (and + (has-bit punch ?width) + (can-orient punch ?orient) + (temperature ?x cold) + (not (busy punch)) + (not (scheduled ?x)) + (not (has-hole ?x ?width ?orient))) + :effect (and + (busy punch) + (scheduled ?x) + (has-hole ?x ?width ?orient) + (surface-condition ?x rough) + (when (not (objscheduled)) + (objscheduled)) + (forall (?oldsurface - surface) + (when (and (surface-condition ?x ?oldsurface) + (not (= ?oldsurface rough))) + (not (surface-condition ?x ?oldsurface)))))) + + (:action do-drill-press + :parameters (?x - part ?width - width ?orient - anorient) + :precondition (and + (has-bit drill-press ?width) + (can-orient drill-press ?orient) + (temperature ?x cold) + (not (busy drill-press)) + (not (scheduled ?x)) + (not (has-hole ?x ?width ?orient))) + :effect (and + (busy drill-press) + (scheduled ?x) + (has-hole ?x ?width ?orient) + (when (not (objscheduled)) + (objscheduled)))) + + (:action do-spray-paint + :parameters (?x - part ?newpaint - colour) + :precondition (and + (has-paint spray-painter ?newpaint) + (not (busy spray-painter)) + (not (scheduled ?x)) + (temperature ?x cold)) + :effect (and + (busy spray-painter) + (scheduled ?x) + (painted ?x ?newpaint) + (when (not (objscheduled)) + (objscheduled)) + (forall (?oldsurface - surface) + (when (surface-condition ?x ?oldsurface) + (not (surface-condition ?x ?oldsurface)))) + (forall (?oldpaint - colour) + (when (and (painted ?x ?oldpaint) + (not (= ?oldpaint ?newpaint))) + (not (painted ?x ?oldpaint)))))) + + (:action do-immersion-paint + :parameters (?x - part ?newpaint - colour) + :precondition (and + (has-paint immersion-painter ?newpaint) + (not (busy immersion-painter)) + (not (scheduled ?x))) + :effect (and + (busy immersion-painter) + (scheduled ?x) + (painted ?x ?newpaint) + (when (not (objscheduled)) + (objscheduled)) + (forall (?oldpaint - colour) + (when (and (painted ?x ?oldpaint) + (not (= ?oldpaint ?newpaint))) + (not (painted ?x ?oldpaint)))))) + + (:action do-time-step + :parameters () + :precondition (objscheduled) + :effect (and + (forall (?x - part) + (when (scheduled ?x) + (not (scheduled ?x)))) + (forall (?m - machine) + (when (busy ?m) + (not (busy ?m))))))) + + + + + + diff --git a/data/schedule/probschedule-51-2.pddl b/data/schedule/probschedule-51-2.pddl new file mode 100644 index 00000000..743c9422 --- /dev/null +++ b/data/schedule/probschedule-51-2.pddl @@ -0,0 +1,400 @@ +(define (problem schedule-51-2) +(:domain schedule) +(:requirements :adl :typing) +(:objects + E2 + D2 + C2 + B2 + A2 + Z1 + W1 + V1 + U1 + S1 + R1 + P1 + Q1 + O1 + N1 + M1 + L1 + K1 + J1 + I1 + H1 + G1 + F1 + E1 + D1 + C1 + B1 + A1 + Z0 + W0 + V0 + U0 + S0 + R0 + P0 + Q0 + O0 + N0 + M0 + L0 + K0 + J0 + I0 + H0 + G0 + F0 + E0 + D0 + C0 + B0 + A0 + - part + CIRCULAR + OBLONG + - ashape + BLUE + YELLOW + RED + BLACK + - colour + TWO + THREE + ONE + - width + BACK + FRONT + - anorient +) +(:init + (SHAPE A0 CYLINDRICAL) + (SURFACE-CONDITION A0 ROUGH) + (PAINTED A0 YELLOW) + (HAS-HOLE A0 ONE FRONT) + (TEMPERATURE A0 COLD) + (SHAPE B0 CYLINDRICAL) + (SURFACE-CONDITION B0 POLISHED) + (PAINTED B0 YELLOW) + (HAS-HOLE B0 ONE BACK) + (TEMPERATURE B0 COLD) + (SHAPE C0 OBLONG) + (SURFACE-CONDITION C0 ROUGH) + (PAINTED C0 RED) + (HAS-HOLE C0 THREE BACK) + (TEMPERATURE C0 COLD) + (SHAPE D0 CYLINDRICAL) + (SURFACE-CONDITION D0 ROUGH) + (PAINTED D0 RED) + (HAS-HOLE D0 TWO FRONT) + (TEMPERATURE D0 COLD) + (SHAPE E0 CYLINDRICAL) + (SURFACE-CONDITION E0 SMOOTH) + (PAINTED E0 BLUE) + (HAS-HOLE E0 THREE BACK) + (TEMPERATURE E0 COLD) + (SHAPE F0 CYLINDRICAL) + (SURFACE-CONDITION F0 ROUGH) + (PAINTED F0 BLACK) + (HAS-HOLE F0 TWO BACK) + (TEMPERATURE F0 COLD) + (SHAPE G0 OBLONG) + (SURFACE-CONDITION G0 POLISHED) + (PAINTED G0 BLUE) + (HAS-HOLE G0 ONE FRONT) + (TEMPERATURE G0 COLD) + (SHAPE H0 CIRCULAR) + (SURFACE-CONDITION H0 POLISHED) + (PAINTED H0 YELLOW) + (HAS-HOLE H0 THREE FRONT) + (TEMPERATURE H0 COLD) + (SHAPE I0 CIRCULAR) + (SURFACE-CONDITION I0 SMOOTH) + (PAINTED I0 BLACK) + (HAS-HOLE I0 THREE BACK) + (TEMPERATURE I0 COLD) + (SHAPE J0 OBLONG) + (SURFACE-CONDITION J0 ROUGH) + (PAINTED J0 RED) + (HAS-HOLE J0 ONE FRONT) + (TEMPERATURE J0 COLD) + (SHAPE K0 CIRCULAR) + (SURFACE-CONDITION K0 ROUGH) + (PAINTED K0 YELLOW) + (HAS-HOLE K0 ONE FRONT) + (TEMPERATURE K0 COLD) + (SHAPE L0 OBLONG) + (SURFACE-CONDITION L0 ROUGH) + (PAINTED L0 BLUE) + (HAS-HOLE L0 ONE BACK) + (TEMPERATURE L0 COLD) + (SHAPE M0 OBLONG) + (SURFACE-CONDITION M0 SMOOTH) + (PAINTED M0 YELLOW) + (HAS-HOLE M0 ONE BACK) + (TEMPERATURE M0 COLD) + (SHAPE N0 CYLINDRICAL) + (SURFACE-CONDITION N0 POLISHED) + (PAINTED N0 RED) + (HAS-HOLE N0 TWO FRONT) + (TEMPERATURE N0 COLD) + (SHAPE O0 CYLINDRICAL) + (SURFACE-CONDITION O0 SMOOTH) + (PAINTED O0 RED) + (HAS-HOLE O0 ONE BACK) + (TEMPERATURE O0 COLD) + (SHAPE Q0 CYLINDRICAL) + (SURFACE-CONDITION Q0 SMOOTH) + (PAINTED Q0 RED) + (HAS-HOLE Q0 TWO BACK) + (TEMPERATURE Q0 COLD) + (SHAPE P0 CIRCULAR) + (SURFACE-CONDITION P0 SMOOTH) + (PAINTED P0 BLACK) + (HAS-HOLE P0 THREE FRONT) + (TEMPERATURE P0 COLD) + (SHAPE R0 CYLINDRICAL) + (SURFACE-CONDITION R0 SMOOTH) + (PAINTED R0 BLUE) + (HAS-HOLE R0 ONE FRONT) + (TEMPERATURE R0 COLD) + (SHAPE S0 CIRCULAR) + (SURFACE-CONDITION S0 SMOOTH) + (PAINTED S0 RED) + (HAS-HOLE S0 TWO BACK) + (TEMPERATURE S0 COLD) + (SHAPE U0 CIRCULAR) + (SURFACE-CONDITION U0 SMOOTH) + (PAINTED U0 BLACK) + (HAS-HOLE U0 TWO BACK) + (TEMPERATURE U0 COLD) + (SHAPE V0 CYLINDRICAL) + (SURFACE-CONDITION V0 ROUGH) + (PAINTED V0 RED) + (HAS-HOLE V0 TWO FRONT) + (TEMPERATURE V0 COLD) + (SHAPE W0 CIRCULAR) + (SURFACE-CONDITION W0 ROUGH) + (PAINTED W0 YELLOW) + (HAS-HOLE W0 THREE FRONT) + (TEMPERATURE W0 COLD) + (SHAPE Z0 CIRCULAR) + (SURFACE-CONDITION Z0 SMOOTH) + (PAINTED Z0 BLACK) + (HAS-HOLE Z0 THREE FRONT) + (TEMPERATURE Z0 COLD) + (SHAPE A1 OBLONG) + (SURFACE-CONDITION A1 POLISHED) + (PAINTED A1 BLUE) + (HAS-HOLE A1 TWO BACK) + (TEMPERATURE A1 COLD) + (SHAPE B1 CIRCULAR) + (SURFACE-CONDITION B1 ROUGH) + (PAINTED B1 YELLOW) + (HAS-HOLE B1 TWO FRONT) + (TEMPERATURE B1 COLD) + (SHAPE C1 CIRCULAR) + (SURFACE-CONDITION C1 ROUGH) + (PAINTED C1 BLACK) + (HAS-HOLE C1 THREE FRONT) + (TEMPERATURE C1 COLD) + (SHAPE D1 OBLONG) + (SURFACE-CONDITION D1 POLISHED) + (PAINTED D1 RED) + (HAS-HOLE D1 ONE BACK) + (TEMPERATURE D1 COLD) + (SHAPE E1 OBLONG) + (SURFACE-CONDITION E1 ROUGH) + (PAINTED E1 RED) + (HAS-HOLE E1 TWO BACK) + (TEMPERATURE E1 COLD) + (SHAPE F1 OBLONG) + (SURFACE-CONDITION F1 ROUGH) + (PAINTED F1 YELLOW) + (HAS-HOLE F1 ONE BACK) + (TEMPERATURE F1 COLD) + (SHAPE G1 CIRCULAR) + (SURFACE-CONDITION G1 ROUGH) + (PAINTED G1 YELLOW) + (HAS-HOLE G1 ONE BACK) + (TEMPERATURE G1 COLD) + (SHAPE H1 OBLONG) + (SURFACE-CONDITION H1 POLISHED) + (PAINTED H1 BLUE) + (HAS-HOLE H1 ONE FRONT) + (TEMPERATURE H1 COLD) + (SHAPE I1 OBLONG) + (SURFACE-CONDITION I1 POLISHED) + (PAINTED I1 RED) + (HAS-HOLE I1 TWO BACK) + (TEMPERATURE I1 COLD) + (SHAPE J1 CYLINDRICAL) + (SURFACE-CONDITION J1 ROUGH) + (PAINTED J1 BLACK) + (HAS-HOLE J1 TWO FRONT) + (TEMPERATURE J1 COLD) + (SHAPE K1 OBLONG) + (SURFACE-CONDITION K1 SMOOTH) + (PAINTED K1 BLUE) + (HAS-HOLE K1 ONE FRONT) + (TEMPERATURE K1 COLD) + (SHAPE L1 CYLINDRICAL) + (SURFACE-CONDITION L1 SMOOTH) + (PAINTED L1 RED) + (HAS-HOLE L1 THREE FRONT) + (TEMPERATURE L1 COLD) + (SHAPE M1 OBLONG) + (SURFACE-CONDITION M1 POLISHED) + (PAINTED M1 YELLOW) + (HAS-HOLE M1 ONE BACK) + (TEMPERATURE M1 COLD) + (SHAPE N1 CIRCULAR) + (SURFACE-CONDITION N1 ROUGH) + (PAINTED N1 YELLOW) + (HAS-HOLE N1 THREE FRONT) + (TEMPERATURE N1 COLD) + (SHAPE O1 CYLINDRICAL) + (SURFACE-CONDITION O1 SMOOTH) + (PAINTED O1 YELLOW) + (HAS-HOLE O1 TWO BACK) + (TEMPERATURE O1 COLD) + (SHAPE Q1 CIRCULAR) + (SURFACE-CONDITION Q1 SMOOTH) + (PAINTED Q1 BLACK) + (HAS-HOLE Q1 TWO FRONT) + (TEMPERATURE Q1 COLD) + (SHAPE P1 CIRCULAR) + (SURFACE-CONDITION P1 POLISHED) + (PAINTED P1 BLACK) + (HAS-HOLE P1 TWO BACK) + (TEMPERATURE P1 COLD) + (SHAPE R1 CIRCULAR) + (SURFACE-CONDITION R1 ROUGH) + (PAINTED R1 BLACK) + (HAS-HOLE R1 ONE BACK) + (TEMPERATURE R1 COLD) + (SHAPE S1 OBLONG) + (SURFACE-CONDITION S1 SMOOTH) + (PAINTED S1 BLACK) + (HAS-HOLE S1 TWO BACK) + (TEMPERATURE S1 COLD) + (SHAPE U1 CYLINDRICAL) + (SURFACE-CONDITION U1 SMOOTH) + (PAINTED U1 YELLOW) + (HAS-HOLE U1 THREE FRONT) + (TEMPERATURE U1 COLD) + (SHAPE V1 CYLINDRICAL) + (SURFACE-CONDITION V1 ROUGH) + (PAINTED V1 YELLOW) + (HAS-HOLE V1 THREE BACK) + (TEMPERATURE V1 COLD) + (SHAPE W1 CYLINDRICAL) + (SURFACE-CONDITION W1 POLISHED) + (PAINTED W1 RED) + (HAS-HOLE W1 TWO BACK) + (TEMPERATURE W1 COLD) + (SHAPE Z1 OBLONG) + (SURFACE-CONDITION Z1 POLISHED) + (PAINTED Z1 YELLOW) + (HAS-HOLE Z1 ONE BACK) + (TEMPERATURE Z1 COLD) + (SHAPE A2 CIRCULAR) + (SURFACE-CONDITION A2 ROUGH) + (PAINTED A2 BLUE) + (HAS-HOLE A2 ONE FRONT) + (TEMPERATURE A2 COLD) + (SHAPE B2 CIRCULAR) + (SURFACE-CONDITION B2 POLISHED) + (PAINTED B2 RED) + (HAS-HOLE B2 THREE BACK) + (TEMPERATURE B2 COLD) + (SHAPE C2 CIRCULAR) + (SURFACE-CONDITION C2 SMOOTH) + (PAINTED C2 YELLOW) + (HAS-HOLE C2 TWO FRONT) + (TEMPERATURE C2 COLD) + (SHAPE D2 CIRCULAR) + (SURFACE-CONDITION D2 SMOOTH) + (PAINTED D2 YELLOW) + (HAS-HOLE D2 TWO BACK) + (TEMPERATURE D2 COLD) + (SHAPE E2 CYLINDRICAL) + (SURFACE-CONDITION E2 POLISHED) + (PAINTED E2 RED) + (HAS-HOLE E2 THREE BACK) + (TEMPERATURE E2 COLD) + (CAN-ORIENT DRILL-PRESS BACK) + (CAN-ORIENT PUNCH BACK) + (CAN-ORIENT DRILL-PRESS FRONT) + (CAN-ORIENT PUNCH FRONT) + (HAS-PAINT IMMERSION-PAINTER YELLOW) + (HAS-PAINT SPRAY-PAINTER YELLOW) + (HAS-PAINT IMMERSION-PAINTER BLUE) + (HAS-PAINT SPRAY-PAINTER BLUE) + (HAS-PAINT IMMERSION-PAINTER BLACK) + (HAS-PAINT SPRAY-PAINTER BLACK) + (HAS-PAINT IMMERSION-PAINTER RED) + (HAS-PAINT SPRAY-PAINTER RED) + (HAS-BIT DRILL-PRESS THREE) + (HAS-BIT PUNCH THREE) + (HAS-BIT DRILL-PRESS TWO) + (HAS-BIT PUNCH TWO) + (HAS-BIT DRILL-PRESS ONE) + (HAS-BIT PUNCH ONE) +) +(:goal (and + (PAINTED A0 BLUE) + (SURFACE-CONDITION U0 ROUGH) + (SURFACE-CONDITION C0 SMOOTH) + (SURFACE-CONDITION Q0 POLISHED) + (SHAPE G0 CYLINDRICAL) + (SHAPE J0 CYLINDRICAL) + (PAINTED C1 RED) + (SHAPE M0 CYLINDRICAL) + (SHAPE U0 CYLINDRICAL) + (SURFACE-CONDITION B0 ROUGH) + (SURFACE-CONDITION S0 ROUGH) + (SURFACE-CONDITION B2 SMOOTH) + (PAINTED A2 BLACK) + (PAINTED H0 BLACK) + (PAINTED N1 RED) + (PAINTED I1 BLUE) + (PAINTED Z0 YELLOW) + (SHAPE E1 CYLINDRICAL) + (SURFACE-CONDITION E2 ROUGH) + (SHAPE K1 CYLINDRICAL) + (PAINTED A1 BLACK) + (SURFACE-CONDITION O0 POLISHED) + (SHAPE H1 CYLINDRICAL) + (SHAPE I0 CYLINDRICAL) + (PAINTED Q1 BLUE) + (SHAPE A2 CYLINDRICAL) + (SURFACE-CONDITION M1 ROUGH) + (SURFACE-CONDITION R1 POLISHED) + (SURFACE-CONDITION I0 ROUGH) + (PAINTED G1 BLACK) + (PAINTED J1 YELLOW) + (SURFACE-CONDITION B1 POLISHED) + (SURFACE-CONDITION E0 POLISHED) + (PAINTED B2 YELLOW) + (PAINTED F1 BLACK) + (PAINTED B0 RED) + (SURFACE-CONDITION Z0 ROUGH) + (PAINTED I0 YELLOW) + (PAINTED V0 YELLOW) + (SHAPE B1 CYLINDRICAL) + (SHAPE M1 CYLINDRICAL) + (PAINTED U0 RED) + (PAINTED D0 BLUE) + (SURFACE-CONDITION J1 POLISHED) + (SURFACE-CONDITION F0 POLISHED) + (PAINTED M0 BLACK) + (PAINTED W0 RED) + (SURFACE-CONDITION H0 ROUGH) + (PAINTED H1 YELLOW) + (SHAPE D1 CYLINDRICAL) + (SURFACE-CONDITION P0 POLISHED) +))) diff --git a/data/woodworking-sat08-strips/domain.pddl b/data/woodworking-sat08-strips/domain.pddl new file mode 100644 index 00000000..2597e627 --- /dev/null +++ b/data/woodworking-sat08-strips/domain.pddl @@ -0,0 +1,283 @@ +;; Woodworking +;; + +(define (domain woodworking) + (:requirements :typing :action-costs) + (:types + acolour awood woodobj machine + surface treatmentstatus + aboardsize apartsize - object + highspeed-saw glazer grinder immersion-varnisher + planer saw spray-varnisher - machine + board part - woodobj) + + (:constants + verysmooth smooth rough - surface + varnished glazed untreated colourfragments - treatmentstatus + natural - acolour + small medium large - apartsize) + + (:predicates + (unused ?obj - part) + (available ?obj - woodobj) + + (surface-condition ?obj - woodobj ?surface - surface) + (treatment ?obj - part ?treatment - treatmentstatus) + (colour ?obj - part ?colour - acolour) + (wood ?obj - woodobj ?wood - awood) + (boardsize ?board - board ?size - aboardsize) + (goalsize ?part - part ?size - apartsize) + (boardsize-successor ?size1 ?size2 - aboardsize) + + (in-highspeed-saw ?b - board ?m - highspeed-saw) + (empty ?m - highspeed-saw) + (has-colour ?machine - machine ?colour - acolour) + (contains-part ?b - board ?p - part) + (grind-treatment-change ?old ?new - treatmentstatus) + (is-smooth ?surface - surface)) + + (:functions (total-cost) - number + (spray-varnish-cost ?obj - part) - number + (glaze-cost ?obj - part) - number + (grind-cost ?obj - part) - number + (plane-cost ?obj - part) - number) + + (:action do-immersion-varnish + :parameters (?x - part ?m - immersion-varnisher + ?newcolour - acolour ?surface - surface) + :precondition (and + (available ?x) + (has-colour ?m ?newcolour) + (surface-condition ?x ?surface) + (is-smooth ?surface) + (treatment ?x untreated)) + :effect (and + (increase (total-cost) 10) + (not (treatment ?x untreated)) + (treatment ?x varnished) + (not (colour ?x natural)) + (colour ?x ?newcolour))) + + (:action do-spray-varnish + :parameters (?x - part ?m - spray-varnisher + ?newcolour - acolour ?surface - surface) + :precondition (and + (available ?x) + (has-colour ?m ?newcolour) + (surface-condition ?x ?surface) + (is-smooth ?surface) + (treatment ?x untreated)) + :effect (and + (increase (total-cost) (spray-varnish-cost ?x)) + (not (treatment ?x untreated)) + (treatment ?x varnished) + (not (colour ?x natural)) + (colour ?x ?newcolour))) + + (:action do-glaze + :parameters (?x - part ?m - glazer + ?newcolour - acolour) + :precondition (and + (available ?x) + (has-colour ?m ?newcolour) + (treatment ?x untreated)) + :effect (and + (increase (total-cost) (glaze-cost ?x)) + (not (treatment ?x untreated)) + (treatment ?x glazed) + (not (colour ?x natural)) + (colour ?x ?newcolour))) + + (:action do-grind + :parameters (?x - part ?m - grinder ?oldsurface - surface + ?oldcolour - acolour + ?oldtreatment ?newtreatment - treatmentstatus) + :precondition (and + (available ?x) + (surface-condition ?x ?oldsurface) + (is-smooth ?oldsurface) + (colour ?x ?oldcolour) + (treatment ?x ?oldtreatment) + (grind-treatment-change ?oldtreatment ?newtreatment)) + :effect (and + (increase (total-cost) (grind-cost ?x)) + (not (surface-condition ?x ?oldsurface)) + (surface-condition ?x verysmooth) + (not (treatment ?x ?oldtreatment)) + (treatment ?x ?newtreatment) + (not (colour ?x ?oldcolour)) + (colour ?x natural))) + + (:action do-plane + :parameters (?x - part ?m - planer ?oldsurface - surface + ?oldcolour - acolour ?oldtreatment - treatmentstatus) + :precondition (and + (available ?x) + (surface-condition ?x ?oldsurface) + (treatment ?x ?oldtreatment) + (colour ?x ?oldcolour)) + :effect (and + (increase (total-cost) (plane-cost ?x)) + (not (surface-condition ?x ?oldsurface)) + (surface-condition ?x smooth) + (not (treatment ?x ?oldtreatment)) + (treatment ?x untreated) + (not (colour ?x ?oldcolour)) + (colour ?x natural))) + + (:action load-highspeed-saw + :parameters (?b - board ?m - highspeed-saw) + :precondition (and + (empty ?m) + (available ?b)) + :effect (and + (increase (total-cost) 30) + (not (available ?b)) + (not (empty ?m)) + (in-highspeed-saw ?b ?m))) + + (:action unload-highspeed-saw + :parameters (?b - board ?m - highspeed-saw) + :precondition (in-highspeed-saw ?b ?m) + :effect (and + (increase (total-cost) 10) + (available ?b) + (not (in-highspeed-saw ?b ?m)) + (empty ?m))) + + (:action cut-board-small + :parameters (?b - board ?p - part ?m - highspeed-saw ?w - awood + ?surface - surface ?size_before ?size_after - aboardsize) + :precondition (and + (unused ?p) + (goalsize ?p small) + (in-highspeed-saw ?b ?m) + (wood ?b ?w) + (surface-condition ?b ?surface) + (boardsize ?b ?size_before) + (boardsize-successor ?size_after ?size_before)) + :effect (and + (increase (total-cost) 10) + (not (unused ?p)) + (available ?p) + (wood ?p ?w) + (surface-condition ?p ?surface) + (colour ?p natural) + (treatment ?p untreated) + (boardsize ?b ?size_after))) + + (:action cut-board-medium + :parameters (?b - board ?p - part ?m - highspeed-saw ?w - awood + ?surface - surface + ?size_before ?s1 ?size_after - aboardsize) + :precondition (and + (unused ?p) + (goalsize ?p medium) + (in-highspeed-saw ?b ?m) + (wood ?b ?w) + (surface-condition ?b ?surface) + (boardsize ?b ?size_before) + (boardsize-successor ?size_after ?s1) + (boardsize-successor ?s1 ?size_before)) + :effect (and + (increase (total-cost) 10) + (not (unused ?p)) + (available ?p) + (wood ?p ?w) + (surface-condition ?p ?surface) + (colour ?p natural) + (treatment ?p untreated) + (boardsize ?b ?size_after))) + + (:action cut-board-large + :parameters (?b - board ?p - part ?m - highspeed-saw ?w - awood + ?surface - surface + ?size_before ?s1 ?s2 ?size_after - aboardsize) + :precondition (and + (unused ?p) + (goalsize ?p large) + (in-highspeed-saw ?b ?m) + (wood ?b ?w) + (surface-condition ?b ?surface) + (boardsize ?b ?size_before) + (boardsize-successor ?size_after ?s1) + (boardsize-successor ?s1 ?s2) + (boardsize-successor ?s2 ?size_before)) + :effect (and + (increase (total-cost) 10) + (not (unused ?p)) + (available ?p) + (wood ?p ?w) + (surface-condition ?p ?surface) + (colour ?p natural) + (treatment ?p untreated) + (boardsize ?b ?size_after))) + + (:action do-saw-small + :parameters (?b - board ?p - part ?m - saw ?w - awood + ?surface - surface ?size_before ?size_after - aboardsize) + :precondition (and + (unused ?p) + (goalsize ?p small) + (available ?b) + (wood ?b ?w) + (surface-condition ?b ?surface) + (boardsize ?b ?size_before) + (boardsize-successor ?size_after ?size_before)) + :effect (and + (increase (total-cost) 30) + (not (unused ?p)) + (available ?p) + (wood ?p ?w) + (surface-condition ?p ?surface) + (colour ?p natural) + (treatment ?p untreated) + (boardsize ?b ?size_after))) + + (:action do-saw-medium + :parameters (?b - board ?p - part ?m - saw ?w - awood + ?surface - surface + ?size_before ?s1 ?size_after - aboardsize) + :precondition (and + (unused ?p) + (goalsize ?p medium) + (available ?b) + (wood ?b ?w) + (surface-condition ?b ?surface) + (boardsize ?b ?size_before) + (boardsize-successor ?size_after ?s1) + (boardsize-successor ?s1 ?size_before)) + :effect (and + (increase (total-cost) 30) + (not (unused ?p)) + (available ?p) + (wood ?p ?w) + (surface-condition ?p ?surface) + (colour ?p natural) + (treatment ?p untreated) + (boardsize ?b ?size_after))) + + (:action do-saw-large + :parameters (?b - board ?p - part ?m - saw ?w - awood + ?surface - surface + ?size_before ?s1 ?s2 ?size_after - aboardsize) + :precondition (and + (unused ?p) + (goalsize ?p large) + (available ?b) + (wood ?b ?w) + (surface-condition ?b ?surface) + (boardsize ?b ?size_before) + (boardsize-successor ?size_after ?s1) + (boardsize-successor ?s1 ?s2) + (boardsize-successor ?s2 ?size_before)) + :effect (and + (increase (total-cost) 30) + (not (unused ?p)) + (available ?p) + (wood ?p ?w) + (surface-condition ?p ?surface) + (colour ?p natural) + (treatment ?p untreated) + (boardsize ?b ?size_after))) +) diff --git a/data/woodworking-sat08-strips/domain_fixed.pddl b/data/woodworking-sat08-strips/domain_fixed.pddl new file mode 100644 index 00000000..fbb89081 --- /dev/null +++ b/data/woodworking-sat08-strips/domain_fixed.pddl @@ -0,0 +1,282 @@ +;; Woodworking +;; + +(define (domain woodworking) + (:requirements :typing :action-costs :numeric-fluents) + (:types + acolour awood woodobj machine + surface treatmentstatus + aboardsize apartsize - object + highspeed-saw glazer grinder immersion-varnisher + planer saw spray-varnisher - machine + board part - woodobj) + + (:constants + verysmooth smooth rough - surface + varnished glazed untreated colourfragments - treatmentstatus + natural - acolour + small medium large - apartsize) + + (:predicates + (unused ?obj - part) + (available ?obj - woodobj) + + (surface-condition ?obj - woodobj ?surface - surface) + (treatment ?obj - part ?treatment - treatmentstatus) + (colour ?obj - part ?colour - acolour) + (wood ?obj - woodobj ?wood - awood) + (boardsize ?board - board ?size - aboardsize) + (goalsize ?part - part ?size - apartsize) + (boardsize-successor ?size1 ?size2 - aboardsize) + + (in-highspeed-saw ?b - board ?m - highspeed-saw) + (empty ?m - highspeed-saw) + (has-colour ?machine - machine ?colour - acolour) + (grind-treatment-change ?old ?new - treatmentstatus) + (is-smooth ?surface - surface)) + + (:functions (total-cost) - number + (spray-varnish-cost ?obj - part) - number + (glaze-cost ?obj - part) - number + (grind-cost ?obj - part) - number + (plane-cost ?obj - part) - number) + + (:action do-immersion-varnish + :parameters (?x - part ?m - immersion-varnisher + ?newcolour - acolour ?surface - surface) + :precondition (and + (available ?x) + (has-colour ?m ?newcolour) + (surface-condition ?x ?surface) + (is-smooth ?surface) + (treatment ?x untreated)) + :effect (and + (increase (total-cost) 10) + (not (treatment ?x untreated)) + (treatment ?x varnished) + (not (colour ?x natural)) + (colour ?x ?newcolour))) + + (:action do-spray-varnish + :parameters (?x - part ?m - spray-varnisher + ?newcolour - acolour ?surface - surface) + :precondition (and + (available ?x) + (has-colour ?m ?newcolour) + (surface-condition ?x ?surface) + (is-smooth ?surface) + (treatment ?x untreated)) + :effect (and + (increase (total-cost) (spray-varnish-cost ?x)) + (not (treatment ?x untreated)) + (treatment ?x varnished) + (not (colour ?x natural)) + (colour ?x ?newcolour))) + + (:action do-glaze + :parameters (?x - part ?m - glazer + ?newcolour - acolour) + :precondition (and + (available ?x) + (has-colour ?m ?newcolour) + (treatment ?x untreated)) + :effect (and + (increase (total-cost) (glaze-cost ?x)) + (not (treatment ?x untreated)) + (treatment ?x glazed) + (not (colour ?x natural)) + (colour ?x ?newcolour))) + + (:action do-grind + :parameters (?x - part ?oldsurface - surface + ?oldcolour - acolour + ?oldtreatment ?newtreatment - treatmentstatus) + :precondition (and + (available ?x) + (surface-condition ?x ?oldsurface) + (is-smooth ?oldsurface) + (colour ?x ?oldcolour) + (treatment ?x ?oldtreatment) + (grind-treatment-change ?oldtreatment ?newtreatment)) + :effect (and + (increase (total-cost) (grind-cost ?x)) + (not (surface-condition ?x ?oldsurface)) + (surface-condition ?x verysmooth) + (not (treatment ?x ?oldtreatment)) + (treatment ?x ?newtreatment) + (not (colour ?x ?oldcolour)) + (colour ?x natural))) + + (:action do-plane + :parameters (?x - part ?oldsurface - surface + ?oldcolour - acolour ?oldtreatment - treatmentstatus) + :precondition (and + (available ?x) + (surface-condition ?x ?oldsurface) + (treatment ?x ?oldtreatment) + (colour ?x ?oldcolour)) + :effect (and + (increase (total-cost) (plane-cost ?x)) + (not (surface-condition ?x ?oldsurface)) + (surface-condition ?x smooth) + (not (treatment ?x ?oldtreatment)) + (treatment ?x untreated) + (not (colour ?x ?oldcolour)) + (colour ?x natural))) + + (:action load-highspeed-saw + :parameters (?b - board ?m - highspeed-saw) + :precondition (and + (empty ?m) + (available ?b)) + :effect (and + (increase (total-cost) 30) + (not (available ?b)) + (not (empty ?m)) + (in-highspeed-saw ?b ?m))) + + (:action unload-highspeed-saw + :parameters (?b - board ?m - highspeed-saw) + :precondition (in-highspeed-saw ?b ?m) + :effect (and + (increase (total-cost) 10) + (available ?b) + (not (in-highspeed-saw ?b ?m)) + (empty ?m))) + + (:action cut-board-small + :parameters (?b - board ?p - part ?m - highspeed-saw ?w - awood + ?surface - surface ?size_before ?size_after - aboardsize) + :precondition (and + (unused ?p) + (goalsize ?p small) + (in-highspeed-saw ?b ?m) + (wood ?b ?w) + (surface-condition ?b ?surface) + (boardsize ?b ?size_before) + (boardsize-successor ?size_after ?size_before)) + :effect (and + (increase (total-cost) 10) + (not (unused ?p)) + (available ?p) + (wood ?p ?w) + (surface-condition ?p ?surface) + (colour ?p natural) + (treatment ?p untreated) + (boardsize ?b ?size_after))) + + (:action cut-board-medium + :parameters (?b - board ?p - part ?m - highspeed-saw ?w - awood + ?surface - surface + ?size_before ?s1 ?size_after - aboardsize) + :precondition (and + (unused ?p) + (goalsize ?p medium) + (in-highspeed-saw ?b ?m) + (wood ?b ?w) + (surface-condition ?b ?surface) + (boardsize ?b ?size_before) + (boardsize-successor ?size_after ?s1) + (boardsize-successor ?s1 ?size_before)) + :effect (and + (increase (total-cost) 10) + (not (unused ?p)) + (available ?p) + (wood ?p ?w) + (surface-condition ?p ?surface) + (colour ?p natural) + (treatment ?p untreated) + (boardsize ?b ?size_after))) + + (:action cut-board-large + :parameters (?b - board ?p - part ?m - highspeed-saw ?w - awood + ?surface - surface + ?size_before ?s1 ?s2 ?size_after - aboardsize) + :precondition (and + (unused ?p) + (goalsize ?p large) + (in-highspeed-saw ?b ?m) + (wood ?b ?w) + (surface-condition ?b ?surface) + (boardsize ?b ?size_before) + (boardsize-successor ?size_after ?s1) + (boardsize-successor ?s1 ?s2) + (boardsize-successor ?s2 ?size_before)) + :effect (and + (increase (total-cost) 10) + (not (unused ?p)) + (available ?p) + (wood ?p ?w) + (surface-condition ?p ?surface) + (colour ?p natural) + (treatment ?p untreated) + (boardsize ?b ?size_after))) + + (:action do-saw-small + :parameters (?b - board ?p - part ?w - awood + ?surface - surface ?size_before ?size_after - aboardsize) + :precondition (and + (unused ?p) + (goalsize ?p small) + (available ?b) + (wood ?b ?w) + (surface-condition ?b ?surface) + (boardsize ?b ?size_before) + (boardsize-successor ?size_after ?size_before)) + :effect (and + (increase (total-cost) 30) + (not (unused ?p)) + (available ?p) + (wood ?p ?w) + (surface-condition ?p ?surface) + (colour ?p natural) + (treatment ?p untreated) + (boardsize ?b ?size_after))) + + (:action do-saw-medium + :parameters (?b - board ?p - part ?w - awood + ?surface - surface + ?size_before ?s1 ?size_after - aboardsize) + :precondition (and + (unused ?p) + (goalsize ?p medium) + (available ?b) + (wood ?b ?w) + (surface-condition ?b ?surface) + (boardsize ?b ?size_before) + (boardsize-successor ?size_after ?s1) + (boardsize-successor ?s1 ?size_before)) + :effect (and + (increase (total-cost) 30) + (not (unused ?p)) + (available ?p) + (wood ?p ?w) + (surface-condition ?p ?surface) + (colour ?p natural) + (treatment ?p untreated) + (boardsize ?b ?size_after))) + + (:action do-saw-large + :parameters (?b - board ?p - part ?w - awood + ?surface - surface + ?size_before ?s1 ?s2 ?size_after - aboardsize) + :precondition (and + (unused ?p) + (goalsize ?p large) + (available ?b) + (wood ?b ?w) + (surface-condition ?b ?surface) + (boardsize ?b ?size_before) + (boardsize-successor ?size_after ?s1) + (boardsize-successor ?s1 ?s2) + (boardsize-successor ?s2 ?size_before)) + :effect (and + (increase (total-cost) 30) + (not (unused ?p)) + (available ?p) + (wood ?p ?w) + (surface-condition ?p ?surface) + (colour ?p natural) + (treatment ?p untreated) + (boardsize ?b ?size_after))) +) diff --git a/data/woodworking-sat08-strips/p01.pddl b/data/woodworking-sat08-strips/p01.pddl new file mode 100644 index 00000000..8bab2331 --- /dev/null +++ b/data/woodworking-sat08-strips/p01.pddl @@ -0,0 +1,91 @@ +; woodworking task with 3 parts and 140% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 973895 + +(define (problem wood-prob) + (:domain woodworking) + (:requirements :typing :action-costs :numeric-fluents) + (:objects + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + red - acolour + pine teak - awood + p0 p1 p2 - part + b0 - board + s0 s1 s2 s3 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (has-colour glazer0 natural) + (has-colour glazer0 red) + (has-colour immersion-varnisher0 natural) + (has-colour immersion-varnisher0 red) + (empty highspeed-saw0) + (has-colour spray-varnisher0 natural) + (has-colour spray-varnisher0 red) + (available p0) + (colour p0 red) + (wood p0 pine) + (surface-condition p0 smooth) + (treatment p0 varnished) + (goalsize p0 small) + (= (spray-varnish-cost p0) 5) + (= (glaze-cost p0) 10) + (= (grind-cost p0) 15) + (= (plane-cost p0) 10) + (unused p1) + (goalsize p1 medium) + (= (spray-varnish-cost p1) 10) + (= (glaze-cost p1) 15) + (= (grind-cost p1) 30) + (= (plane-cost p1) 20) + (available p2) + (colour p2 natural) + (wood p2 teak) + (surface-condition p2 verysmooth) + (treatment p2 varnished) + (goalsize p2 large) + (= (spray-varnish-cost p2) 15) + (= (glaze-cost p2) 20) + (= (grind-cost p2) 45) + (= (plane-cost p2) 30) + (boardsize b0 s3) + (wood b0 pine) + (surface-condition b0 rough) + (available b0) + ) + (:goal + (and + (available p0) + (colour p0 natural) + (wood p0 pine) + (available p1) + (colour p1 natural) + (wood p1 pine) + (surface-condition p1 smooth) + (treatment p1 varnished) + (available p2) + (colour p2 red) + (wood p2 teak) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p02.pddl b/data/woodworking-sat08-strips/p02.pddl new file mode 100644 index 00000000..4592b735 --- /dev/null +++ b/data/woodworking-sat08-strips/p02.pddl @@ -0,0 +1,132 @@ +; woodworking task with 6 parts and 140% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 887881 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + black blue mauve red - acolour + walnut mahogany - awood + p0 p1 p2 p3 p4 p5 - part + b0 - board + s0 s1 s2 s3 s4 s5 s6 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (has-colour glazer0 blue) + (has-colour immersion-varnisher0 mauve) + (has-colour immersion-varnisher0 black) + (empty highspeed-saw0) + (has-colour spray-varnisher0 mauve) + (has-colour spray-varnisher0 black) + (available p0) + (colour p0 natural) + (wood p0 walnut) + (surface-condition p0 verysmooth) + (treatment p0 glazed) + (goalsize p0 small) + (= (spray-varnish-cost p0) 5) + (= (glaze-cost p0) 10) + (= (grind-cost p0) 15) + (= (plane-cost p0) 10) + (unused p1) + (goalsize p1 medium) + (= (spray-varnish-cost p1) 10) + (= (glaze-cost p1) 15) + (= (grind-cost p1) 30) + (= (plane-cost p1) 20) + (available p2) + (colour p2 black) + (wood p2 mahogany) + (surface-condition p2 rough) + (treatment p2 glazed) + (goalsize p2 large) + (= (spray-varnish-cost p2) 15) + (= (glaze-cost p2) 20) + (= (grind-cost p2) 45) + (= (plane-cost p2) 30) + (unused p3) + (goalsize p3 medium) + (= (spray-varnish-cost p3) 10) + (= (glaze-cost p3) 15) + (= (grind-cost p3) 30) + (= (plane-cost p3) 20) + (available p4) + (colour p4 black) + (wood p4 mahogany) + (surface-condition p4 verysmooth) + (treatment p4 varnished) + (goalsize p4 large) + (= (spray-varnish-cost p4) 15) + (= (glaze-cost p4) 20) + (= (grind-cost p4) 45) + (= (plane-cost p4) 30) + (available p5) + (colour p5 mauve) + (wood p5 walnut) + (surface-condition p5 rough) + (treatment p5 glazed) + (goalsize p5 small) + (= (spray-varnish-cost p5) 5) + (= (glaze-cost p5) 10) + (= (grind-cost p5) 15) + (= (plane-cost p5) 10) + (boardsize b0 s6) + (wood b0 walnut) + (surface-condition b0 smooth) + (available b0) + ) + (:goal + (and + (available p0) + (colour p0 black) + (treatment p0 varnished) + (available p1) + (wood p1 walnut) + (surface-condition p1 smooth) + (treatment p1 glazed) + (available p2) + (colour p2 blue) + (surface-condition p2 verysmooth) + (treatment p2 glazed) + (available p3) + (surface-condition p3 smooth) + (treatment p3 varnished) + (available p4) + (colour p4 mauve) + (wood p4 mahogany) + (surface-condition p4 smooth) + (treatment p4 varnished) + (available p5) + (surface-condition p5 verysmooth) + (treatment p5 varnished) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p03.pddl b/data/woodworking-sat08-strips/p03.pddl new file mode 100644 index 00000000..47345e6a --- /dev/null +++ b/data/woodworking-sat08-strips/p03.pddl @@ -0,0 +1,168 @@ +; woodworking task with 9 parts and 140% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 976727 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + white green blue mauve red black - acolour + teak mahogany - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 - part + b0 b1 b2 b3 - board + s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (boardsize-successor s7 s8) + (boardsize-successor s8 s9) + (boardsize-successor s9 s10) + (has-colour glazer0 mauve) + (has-colour glazer0 natural) + (has-colour immersion-varnisher0 green) + (has-colour immersion-varnisher0 black) + (has-colour immersion-varnisher0 natural) + (has-colour immersion-varnisher0 mauve) + (empty highspeed-saw0) + (has-colour spray-varnisher0 green) + (has-colour spray-varnisher0 black) + (has-colour spray-varnisher0 natural) + (has-colour spray-varnisher0 mauve) + (unused p0) + (goalsize p0 large) + (= (spray-varnish-cost p0) 15) + (= (glaze-cost p0) 20) + (= (grind-cost p0) 45) + (= (plane-cost p0) 30) + (unused p1) + (goalsize p1 large) + (= (spray-varnish-cost p1) 15) + (= (glaze-cost p1) 20) + (= (grind-cost p1) 45) + (= (plane-cost p1) 30) + (unused p2) + (goalsize p2 medium) + (= (spray-varnish-cost p2) 10) + (= (glaze-cost p2) 15) + (= (grind-cost p2) 30) + (= (plane-cost p2) 20) + (unused p3) + (goalsize p3 large) + (= (spray-varnish-cost p3) 15) + (= (glaze-cost p3) 20) + (= (grind-cost p3) 45) + (= (plane-cost p3) 30) + (unused p4) + (goalsize p4 small) + (= (spray-varnish-cost p4) 5) + (= (glaze-cost p4) 10) + (= (grind-cost p4) 15) + (= (plane-cost p4) 10) + (available p5) + (colour p5 blue) + (wood p5 teak) + (surface-condition p5 rough) + (treatment p5 glazed) + (goalsize p5 large) + (= (spray-varnish-cost p5) 15) + (= (glaze-cost p5) 20) + (= (grind-cost p5) 45) + (= (plane-cost p5) 30) + (unused p6) + (goalsize p6 small) + (= (spray-varnish-cost p6) 5) + (= (glaze-cost p6) 10) + (= (grind-cost p6) 15) + (= (plane-cost p6) 10) + (unused p7) + (goalsize p7 medium) + (= (spray-varnish-cost p7) 10) + (= (glaze-cost p7) 15) + (= (grind-cost p7) 30) + (= (plane-cost p7) 20) + (unused p8) + (goalsize p8 large) + (= (spray-varnish-cost p8) 15) + (= (glaze-cost p8) 20) + (= (grind-cost p8) 45) + (= (plane-cost p8) 30) + (boardsize b0 s10) + (wood b0 teak) + (surface-condition b0 rough) + (available b0) + (boardsize b1 s6) + (wood b1 teak) + (surface-condition b1 smooth) + (available b1) + (boardsize b2 s7) + (wood b2 mahogany) + (surface-condition b2 rough) + (available b2) + (boardsize b3 s3) + (wood b3 mahogany) + (surface-condition b3 smooth) + (available b3) + ) + (:goal + (and + (available p0) + (colour p0 green) + (treatment p0 varnished) + (available p1) + (colour p1 black) + (surface-condition p1 verysmooth) + (treatment p1 varnished) + (available p2) + (colour p2 mauve) + (wood p2 teak) + (available p3) + (surface-condition p3 verysmooth) + (treatment p3 glazed) + (available p4) + (wood p4 mahogany) + (treatment p4 varnished) + (available p5) + (surface-condition p5 verysmooth) + (treatment p5 varnished) + (available p6) + (wood p6 mahogany) + (treatment p6 varnished) + (available p7) + (colour p7 natural) + (wood p7 mahogany) + (surface-condition p7 verysmooth) + (treatment p7 varnished) + (available p8) + (colour p8 natural) + (surface-condition p8 smooth) + (treatment p8 glazed) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p04.pddl b/data/woodworking-sat08-strips/p04.pddl new file mode 100644 index 00000000..2d298881 --- /dev/null +++ b/data/woodworking-sat08-strips/p04.pddl @@ -0,0 +1,205 @@ +; woodworking task with 12 parts and 140% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 686037 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + mauve green white red blue black - acolour + beech oak pine - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 - part + b0 b1 b2 b3 - board + s0 s1 s2 s3 s4 s5 s6 s7 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (has-colour glazer0 white) + (has-colour glazer0 red) + (has-colour immersion-varnisher0 mauve) + (has-colour immersion-varnisher0 white) + (has-colour immersion-varnisher0 natural) + (has-colour immersion-varnisher0 red) + (empty highspeed-saw0) + (has-colour spray-varnisher0 mauve) + (has-colour spray-varnisher0 white) + (has-colour spray-varnisher0 natural) + (has-colour spray-varnisher0 red) + (unused p0) + (goalsize p0 medium) + (= (spray-varnish-cost p0) 10) + (= (glaze-cost p0) 15) + (= (grind-cost p0) 30) + (= (plane-cost p0) 20) + (unused p1) + (goalsize p1 medium) + (= (spray-varnish-cost p1) 10) + (= (glaze-cost p1) 15) + (= (grind-cost p1) 30) + (= (plane-cost p1) 20) + (unused p2) + (goalsize p2 small) + (= (spray-varnish-cost p2) 5) + (= (glaze-cost p2) 10) + (= (grind-cost p2) 15) + (= (plane-cost p2) 10) + (unused p3) + (goalsize p3 small) + (= (spray-varnish-cost p3) 5) + (= (glaze-cost p3) 10) + (= (grind-cost p3) 15) + (= (plane-cost p3) 10) + (unused p4) + (goalsize p4 large) + (= (spray-varnish-cost p4) 15) + (= (glaze-cost p4) 20) + (= (grind-cost p4) 45) + (= (plane-cost p4) 30) + (unused p5) + (goalsize p5 large) + (= (spray-varnish-cost p5) 15) + (= (glaze-cost p5) 20) + (= (grind-cost p5) 45) + (= (plane-cost p5) 30) + (unused p6) + (goalsize p6 medium) + (= (spray-varnish-cost p6) 10) + (= (glaze-cost p6) 15) + (= (grind-cost p6) 30) + (= (plane-cost p6) 20) + (available p7) + (colour p7 blue) + (wood p7 oak) + (surface-condition p7 rough) + (treatment p7 varnished) + (goalsize p7 medium) + (= (spray-varnish-cost p7) 10) + (= (glaze-cost p7) 15) + (= (grind-cost p7) 30) + (= (plane-cost p7) 20) + (available p8) + (colour p8 blue) + (wood p8 beech) + (surface-condition p8 smooth) + (treatment p8 glazed) + (goalsize p8 large) + (= (spray-varnish-cost p8) 15) + (= (glaze-cost p8) 20) + (= (grind-cost p8) 45) + (= (plane-cost p8) 30) + (unused p9) + (goalsize p9 small) + (= (spray-varnish-cost p9) 5) + (= (glaze-cost p9) 10) + (= (grind-cost p9) 15) + (= (plane-cost p9) 10) + (unused p10) + (goalsize p10 medium) + (= (spray-varnish-cost p10) 10) + (= (glaze-cost p10) 15) + (= (grind-cost p10) 30) + (= (plane-cost p10) 20) + (unused p11) + (goalsize p11 small) + (= (spray-varnish-cost p11) 5) + (= (glaze-cost p11) 10) + (= (grind-cost p11) 15) + (= (plane-cost p11) 10) + (boardsize b0 s6) + (wood b0 beech) + (surface-condition b0 rough) + (available b0) + (boardsize b1 s7) + (wood b1 beech) + (surface-condition b1 rough) + (available b1) + (boardsize b2 s6) + (wood b2 oak) + (surface-condition b2 rough) + (available b2) + (boardsize b3 s7) + (wood b3 pine) + (surface-condition b3 rough) + (available b3) + ) + (:goal + (and + (available p0) + (colour p0 red) + (wood p0 beech) + (surface-condition p0 verysmooth) + (treatment p0 glazed) + (available p1) + (wood p1 pine) + (surface-condition p1 verysmooth) + (available p2) + (surface-condition p2 verysmooth) + (treatment p2 glazed) + (available p3) + (colour p3 natural) + (wood p3 beech) + (surface-condition p3 verysmooth) + (treatment p3 varnished) + (available p4) + (colour p4 natural) + (wood p4 oak) + (surface-condition p4 smooth) + (treatment p4 varnished) + (available p5) + (colour p5 red) + (surface-condition p5 smooth) + (available p6) + (colour p6 natural) + (wood p6 beech) + (surface-condition p6 verysmooth) + (treatment p6 varnished) + (available p7) + (colour p7 mauve) + (surface-condition p7 smooth) + (treatment p7 varnished) + (available p8) + (colour p8 white) + (wood p8 beech) + (surface-condition p8 verysmooth) + (available p9) + (surface-condition p9 verysmooth) + (treatment p9 varnished) + (available p10) + (wood p10 pine) + (surface-condition p10 verysmooth) + (treatment p10 glazed) + (available p11) + (colour p11 red) + (wood p11 oak) + (surface-condition p11 verysmooth) + (treatment p11 glazed) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p05.pddl b/data/woodworking-sat08-strips/p05.pddl new file mode 100644 index 00000000..f44f87d8 --- /dev/null +++ b/data/woodworking-sat08-strips/p05.pddl @@ -0,0 +1,243 @@ +; woodworking task with 15 parts and 140% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 627360 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + red black mauve blue green white - acolour + teak cherry walnut pine - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 - part + b0 b1 b2 b3 b4 b5 - board + s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (boardsize-successor s7 s8) + (boardsize-successor s8 s9) + (has-colour glazer0 green) + (has-colour glazer0 red) + (has-colour immersion-varnisher0 mauve) + (has-colour immersion-varnisher0 white) + (has-colour immersion-varnisher0 green) + (has-colour immersion-varnisher0 red) + (empty highspeed-saw0) + (has-colour spray-varnisher0 mauve) + (has-colour spray-varnisher0 white) + (has-colour spray-varnisher0 green) + (has-colour spray-varnisher0 red) + (unused p0) + (goalsize p0 medium) + (= (spray-varnish-cost p0) 10) + (= (glaze-cost p0) 15) + (= (grind-cost p0) 30) + (= (plane-cost p0) 20) + (unused p1) + (goalsize p1 medium) + (= (spray-varnish-cost p1) 10) + (= (glaze-cost p1) 15) + (= (grind-cost p1) 30) + (= (plane-cost p1) 20) + (unused p2) + (goalsize p2 large) + (= (spray-varnish-cost p2) 15) + (= (glaze-cost p2) 20) + (= (grind-cost p2) 45) + (= (plane-cost p2) 30) + (unused p3) + (goalsize p3 small) + (= (spray-varnish-cost p3) 5) + (= (glaze-cost p3) 10) + (= (grind-cost p3) 15) + (= (plane-cost p3) 10) + (unused p4) + (goalsize p4 small) + (= (spray-varnish-cost p4) 5) + (= (glaze-cost p4) 10) + (= (grind-cost p4) 15) + (= (plane-cost p4) 10) + (unused p5) + (goalsize p5 medium) + (= (spray-varnish-cost p5) 10) + (= (glaze-cost p5) 15) + (= (grind-cost p5) 30) + (= (plane-cost p5) 20) + (unused p6) + (goalsize p6 small) + (= (spray-varnish-cost p6) 5) + (= (glaze-cost p6) 10) + (= (grind-cost p6) 15) + (= (plane-cost p6) 10) + (unused p7) + (goalsize p7 small) + (= (spray-varnish-cost p7) 5) + (= (glaze-cost p7) 10) + (= (grind-cost p7) 15) + (= (plane-cost p7) 10) + (unused p8) + (goalsize p8 large) + (= (spray-varnish-cost p8) 15) + (= (glaze-cost p8) 20) + (= (grind-cost p8) 45) + (= (plane-cost p8) 30) + (available p9) + (colour p9 natural) + (wood p9 pine) + (surface-condition p9 smooth) + (treatment p9 glazed) + (goalsize p9 medium) + (= (spray-varnish-cost p9) 10) + (= (glaze-cost p9) 15) + (= (grind-cost p9) 30) + (= (plane-cost p9) 20) + (unused p10) + (goalsize p10 small) + (= (spray-varnish-cost p10) 5) + (= (glaze-cost p10) 10) + (= (grind-cost p10) 15) + (= (plane-cost p10) 10) + (unused p11) + (goalsize p11 small) + (= (spray-varnish-cost p11) 5) + (= (glaze-cost p11) 10) + (= (grind-cost p11) 15) + (= (plane-cost p11) 10) + (available p12) + (colour p12 mauve) + (wood p12 teak) + (surface-condition p12 verysmooth) + (treatment p12 colourfragments) + (goalsize p12 small) + (= (spray-varnish-cost p12) 5) + (= (glaze-cost p12) 10) + (= (grind-cost p12) 15) + (= (plane-cost p12) 10) + (unused p13) + (goalsize p13 large) + (= (spray-varnish-cost p13) 15) + (= (glaze-cost p13) 20) + (= (grind-cost p13) 45) + (= (plane-cost p13) 30) + (unused p14) + (goalsize p14 small) + (= (spray-varnish-cost p14) 5) + (= (glaze-cost p14) 10) + (= (grind-cost p14) 15) + (= (plane-cost p14) 10) + (boardsize b0 s6) + (wood b0 cherry) + (surface-condition b0 rough) + (available b0) + (boardsize b1 s1) + (wood b1 cherry) + (surface-condition b1 smooth) + (available b1) + (boardsize b2 s2) + (wood b2 walnut) + (surface-condition b2 rough) + (available b2) + (boardsize b3 s8) + (wood b3 pine) + (surface-condition b3 rough) + (available b3) + (boardsize b4 s6) + (wood b4 pine) + (surface-condition b4 smooth) + (available b4) + (boardsize b5 s9) + (wood b5 teak) + (surface-condition b5 rough) + (available b5) + ) + (:goal + (and + (available p0) + (colour p0 green) + (wood p0 pine) + (surface-condition p0 smooth) + (treatment p0 glazed) + (available p1) + (colour p1 red) + (surface-condition p1 smooth) + (available p2) + (colour p2 red) + (wood p2 pine) + (surface-condition p2 smooth) + (available p3) + (wood p3 pine) + (treatment p3 varnished) + (available p4) + (colour p4 white) + (wood p4 cherry) + (surface-condition p4 verysmooth) + (treatment p4 varnished) + (available p5) + (colour p5 mauve) + (wood p5 teak) + (surface-condition p5 smooth) + (treatment p5 varnished) + (available p6) + (surface-condition p6 verysmooth) + (treatment p6 glazed) + (available p7) + (wood p7 cherry) + (treatment p7 glazed) + (available p8) + (colour p8 red) + (surface-condition p8 verysmooth) + (available p9) + (colour p9 red) + (wood p9 pine) + (surface-condition p9 verysmooth) + (treatment p9 varnished) + (available p10) + (wood p10 walnut) + (surface-condition p10 verysmooth) + (treatment p10 varnished) + (available p11) + (colour p11 green) + (wood p11 pine) + (surface-condition p11 verysmooth) + (treatment p11 varnished) + (available p12) + (colour p12 green) + (wood p12 teak) + (surface-condition p12 smooth) + (treatment p12 glazed) + (available p13) + (wood p13 pine) + (surface-condition p13 smooth) + (available p14) + (surface-condition p14 smooth) + (treatment p14 varnished) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p06.pddl b/data/woodworking-sat08-strips/p06.pddl new file mode 100644 index 00000000..4959879b --- /dev/null +++ b/data/woodworking-sat08-strips/p06.pddl @@ -0,0 +1,276 @@ +; woodworking task with 18 parts and 140% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 859097 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + white blue green black mauve red - acolour + mahogany oak pine walnut teak - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 - part + b0 b1 b2 b3 b4 b5 b6 - board + s0 s1 s2 s3 s4 s5 s6 s7 s8 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (boardsize-successor s7 s8) + (has-colour glazer0 natural) + (has-colour glazer0 white) + (has-colour glazer0 green) + (has-colour glazer0 red) + (has-colour glazer0 black) + (has-colour immersion-varnisher0 black) + (has-colour immersion-varnisher0 white) + (has-colour immersion-varnisher0 natural) + (has-colour immersion-varnisher0 red) + (empty highspeed-saw0) + (has-colour spray-varnisher0 black) + (has-colour spray-varnisher0 white) + (has-colour spray-varnisher0 natural) + (has-colour spray-varnisher0 red) + (unused p0) + (goalsize p0 medium) + (= (spray-varnish-cost p0) 10) + (= (glaze-cost p0) 15) + (= (grind-cost p0) 30) + (= (plane-cost p0) 20) + (available p1) + (colour p1 green) + (wood p1 teak) + (surface-condition p1 verysmooth) + (treatment p1 varnished) + (goalsize p1 large) + (= (spray-varnish-cost p1) 15) + (= (glaze-cost p1) 20) + (= (grind-cost p1) 45) + (= (plane-cost p1) 30) + (available p2) + (colour p2 mauve) + (wood p2 mahogany) + (surface-condition p2 smooth) + (treatment p2 glazed) + (goalsize p2 large) + (= (spray-varnish-cost p2) 15) + (= (glaze-cost p2) 20) + (= (grind-cost p2) 45) + (= (plane-cost p2) 30) + (unused p3) + (goalsize p3 small) + (= (spray-varnish-cost p3) 5) + (= (glaze-cost p3) 10) + (= (grind-cost p3) 15) + (= (plane-cost p3) 10) + (unused p4) + (goalsize p4 medium) + (= (spray-varnish-cost p4) 10) + (= (glaze-cost p4) 15) + (= (grind-cost p4) 30) + (= (plane-cost p4) 20) + (unused p5) + (goalsize p5 medium) + (= (spray-varnish-cost p5) 10) + (= (glaze-cost p5) 15) + (= (grind-cost p5) 30) + (= (plane-cost p5) 20) + (unused p6) + (goalsize p6 large) + (= (spray-varnish-cost p6) 15) + (= (glaze-cost p6) 20) + (= (grind-cost p6) 45) + (= (plane-cost p6) 30) + (available p7) + (colour p7 blue) + (wood p7 pine) + (surface-condition p7 rough) + (treatment p7 colourfragments) + (goalsize p7 medium) + (= (spray-varnish-cost p7) 10) + (= (glaze-cost p7) 15) + (= (grind-cost p7) 30) + (= (plane-cost p7) 20) + (unused p8) + (goalsize p8 small) + (= (spray-varnish-cost p8) 5) + (= (glaze-cost p8) 10) + (= (grind-cost p8) 15) + (= (plane-cost p8) 10) + (unused p9) + (goalsize p9 medium) + (= (spray-varnish-cost p9) 10) + (= (glaze-cost p9) 15) + (= (grind-cost p9) 30) + (= (plane-cost p9) 20) + (unused p10) + (goalsize p10 small) + (= (spray-varnish-cost p10) 5) + (= (glaze-cost p10) 10) + (= (grind-cost p10) 15) + (= (plane-cost p10) 10) + (unused p11) + (goalsize p11 large) + (= (spray-varnish-cost p11) 15) + (= (glaze-cost p11) 20) + (= (grind-cost p11) 45) + (= (plane-cost p11) 30) + (unused p12) + (goalsize p12 small) + (= (spray-varnish-cost p12) 5) + (= (glaze-cost p12) 10) + (= (grind-cost p12) 15) + (= (plane-cost p12) 10) + (unused p13) + (goalsize p13 small) + (= (spray-varnish-cost p13) 5) + (= (glaze-cost p13) 10) + (= (grind-cost p13) 15) + (= (plane-cost p13) 10) + (unused p14) + (goalsize p14 medium) + (= (spray-varnish-cost p14) 10) + (= (glaze-cost p14) 15) + (= (grind-cost p14) 30) + (= (plane-cost p14) 20) + (unused p15) + (goalsize p15 medium) + (= (spray-varnish-cost p15) 10) + (= (glaze-cost p15) 15) + (= (grind-cost p15) 30) + (= (plane-cost p15) 20) + (unused p16) + (goalsize p16 small) + (= (spray-varnish-cost p16) 5) + (= (glaze-cost p16) 10) + (= (grind-cost p16) 15) + (= (plane-cost p16) 10) + (unused p17) + (goalsize p17 small) + (= (spray-varnish-cost p17) 5) + (= (glaze-cost p17) 10) + (= (grind-cost p17) 15) + (= (plane-cost p17) 10) + (boardsize b0 s3) + (wood b0 teak) + (surface-condition b0 rough) + (available b0) + (boardsize b1 s6) + (wood b1 mahogany) + (surface-condition b1 rough) + (available b1) + (boardsize b2 s6) + (wood b2 oak) + (surface-condition b2 smooth) + (available b2) + (boardsize b3 s8) + (wood b3 pine) + (surface-condition b3 rough) + (available b3) + (boardsize b4 s4) + (wood b4 pine) + (surface-condition b4 rough) + (available b4) + (boardsize b5 s8) + (wood b5 walnut) + (surface-condition b5 rough) + (available b5) + (boardsize b6 s2) + (wood b6 walnut) + (surface-condition b6 rough) + (available b6) + ) + (:goal + (and + (available p0) + (wood p0 walnut) + (surface-condition p0 verysmooth) + (available p1) + (colour p1 natural) + (wood p1 teak) + (surface-condition p1 verysmooth) + (available p2) + (colour p2 natural) + (surface-condition p2 verysmooth) + (treatment p2 glazed) + (available p3) + (colour p3 black) + (wood p3 pine) + (surface-condition p3 verysmooth) + (treatment p3 varnished) + (available p4) + (colour p4 green) + (wood p4 pine) + (surface-condition p4 smooth) + (treatment p4 glazed) + (available p5) + (wood p5 walnut) + (surface-condition p5 verysmooth) + (treatment p5 glazed) + (available p6) + (colour p6 red) + (wood p6 oak) + (surface-condition p6 smooth) + (treatment p6 varnished) + (available p7) + (wood p7 pine) + (treatment p7 glazed) + (available p8) + (surface-condition p8 smooth) + (treatment p8 glazed) + (available p9) + (colour p9 white) + (wood p9 pine) + (available p10) + (colour p10 black) + (wood p10 oak) + (treatment p10 glazed) + (available p11) + (colour p11 natural) + (wood p11 pine) + (available p12) + (wood p12 walnut) + (surface-condition p12 verysmooth) + (available p13) + (colour p13 natural) + (surface-condition p13 smooth) + (available p14) + (wood p14 mahogany) + (treatment p14 glazed) + (available p15) + (wood p15 mahogany) + (surface-condition p15 verysmooth) + (available p16) + (colour p16 natural) + (treatment p16 varnished) + (available p17) + (colour p17 red) + (wood p17 teak) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p07.pddl b/data/woodworking-sat08-strips/p07.pddl new file mode 100644 index 00000000..581a366c --- /dev/null +++ b/data/woodworking-sat08-strips/p07.pddl @@ -0,0 +1,311 @@ +; woodworking task with 21 parts and 140% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 176206 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + red green blue mauve black white - acolour + mahogany oak beech teak cherry - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 p18 p19 p20 - part + b0 b1 b2 b3 b4 b5 b6 b7 b8 - board + s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (boardsize-successor s7 s8) + (boardsize-successor s8 s9) + (boardsize-successor s9 s10) + (boardsize-successor s10 s11) + (has-colour glazer0 blue) + (has-colour glazer0 black) + (has-colour glazer0 white) + (has-colour glazer0 green) + (has-colour glazer0 mauve) + (has-colour immersion-varnisher0 blue) + (has-colour immersion-varnisher0 mauve) + (has-colour immersion-varnisher0 white) + (has-colour immersion-varnisher0 green) + (has-colour immersion-varnisher0 black) + (empty highspeed-saw0) + (has-colour spray-varnisher0 blue) + (has-colour spray-varnisher0 mauve) + (has-colour spray-varnisher0 white) + (has-colour spray-varnisher0 green) + (has-colour spray-varnisher0 black) + (available p0) + (colour p0 red) + (wood p0 teak) + (surface-condition p0 verysmooth) + (treatment p0 colourfragments) + (goalsize p0 medium) + (= (spray-varnish-cost p0) 10) + (= (glaze-cost p0) 15) + (= (grind-cost p0) 30) + (= (plane-cost p0) 20) + (unused p1) + (goalsize p1 large) + (= (spray-varnish-cost p1) 15) + (= (glaze-cost p1) 20) + (= (grind-cost p1) 45) + (= (plane-cost p1) 30) + (unused p2) + (goalsize p2 medium) + (= (spray-varnish-cost p2) 10) + (= (glaze-cost p2) 15) + (= (grind-cost p2) 30) + (= (plane-cost p2) 20) + (unused p3) + (goalsize p3 small) + (= (spray-varnish-cost p3) 5) + (= (glaze-cost p3) 10) + (= (grind-cost p3) 15) + (= (plane-cost p3) 10) + (unused p4) + (goalsize p4 medium) + (= (spray-varnish-cost p4) 10) + (= (glaze-cost p4) 15) + (= (grind-cost p4) 30) + (= (plane-cost p4) 20) + (unused p5) + (goalsize p5 medium) + (= (spray-varnish-cost p5) 10) + (= (glaze-cost p5) 15) + (= (grind-cost p5) 30) + (= (plane-cost p5) 20) + (unused p6) + (goalsize p6 large) + (= (spray-varnish-cost p6) 15) + (= (glaze-cost p6) 20) + (= (grind-cost p6) 45) + (= (plane-cost p6) 30) + (unused p7) + (goalsize p7 medium) + (= (spray-varnish-cost p7) 10) + (= (glaze-cost p7) 15) + (= (grind-cost p7) 30) + (= (plane-cost p7) 20) + (unused p8) + (goalsize p8 small) + (= (spray-varnish-cost p8) 5) + (= (glaze-cost p8) 10) + (= (grind-cost p8) 15) + (= (plane-cost p8) 10) + (unused p9) + (goalsize p9 medium) + (= (spray-varnish-cost p9) 10) + (= (glaze-cost p9) 15) + (= (grind-cost p9) 30) + (= (plane-cost p9) 20) + (unused p10) + (goalsize p10 small) + (= (spray-varnish-cost p10) 5) + (= (glaze-cost p10) 10) + (= (grind-cost p10) 15) + (= (plane-cost p10) 10) + (unused p11) + (goalsize p11 large) + (= (spray-varnish-cost p11) 15) + (= (glaze-cost p11) 20) + (= (grind-cost p11) 45) + (= (plane-cost p11) 30) + (unused p12) + (goalsize p12 medium) + (= (spray-varnish-cost p12) 10) + (= (glaze-cost p12) 15) + (= (grind-cost p12) 30) + (= (plane-cost p12) 20) + (unused p13) + (goalsize p13 medium) + (= (spray-varnish-cost p13) 10) + (= (glaze-cost p13) 15) + (= (grind-cost p13) 30) + (= (plane-cost p13) 20) + (unused p14) + (goalsize p14 medium) + (= (spray-varnish-cost p14) 10) + (= (glaze-cost p14) 15) + (= (grind-cost p14) 30) + (= (plane-cost p14) 20) + (unused p15) + (goalsize p15 small) + (= (spray-varnish-cost p15) 5) + (= (glaze-cost p15) 10) + (= (grind-cost p15) 15) + (= (plane-cost p15) 10) + (unused p16) + (goalsize p16 small) + (= (spray-varnish-cost p16) 5) + (= (glaze-cost p16) 10) + (= (grind-cost p16) 15) + (= (plane-cost p16) 10) + (unused p17) + (goalsize p17 large) + (= (spray-varnish-cost p17) 15) + (= (glaze-cost p17) 20) + (= (grind-cost p17) 45) + (= (plane-cost p17) 30) + (unused p18) + (goalsize p18 large) + (= (spray-varnish-cost p18) 15) + (= (glaze-cost p18) 20) + (= (grind-cost p18) 45) + (= (plane-cost p18) 30) + (unused p19) + (goalsize p19 medium) + (= (spray-varnish-cost p19) 10) + (= (glaze-cost p19) 15) + (= (grind-cost p19) 30) + (= (plane-cost p19) 20) + (unused p20) + (goalsize p20 large) + (= (spray-varnish-cost p20) 15) + (= (glaze-cost p20) 20) + (= (grind-cost p20) 45) + (= (plane-cost p20) 30) + (boardsize b0 s11) + (wood b0 beech) + (surface-condition b0 rough) + (available b0) + (boardsize b1 s8) + (wood b1 beech) + (surface-condition b1 smooth) + (available b1) + (boardsize b2 s2) + (wood b2 beech) + (surface-condition b2 rough) + (available b2) + (boardsize b3 s7) + (wood b3 teak) + (surface-condition b3 smooth) + (available b3) + (boardsize b4 s5) + (wood b4 teak) + (surface-condition b4 smooth) + (available b4) + (boardsize b5 s9) + (wood b5 mahogany) + (surface-condition b5 rough) + (available b5) + (boardsize b6 s7) + (wood b6 oak) + (surface-condition b6 smooth) + (available b6) + (boardsize b7 s5) + (wood b7 oak) + (surface-condition b7 rough) + (available b7) + (boardsize b8 s6) + (wood b8 cherry) + (surface-condition b8 rough) + (available b8) + ) + (:goal + (and + (available p0) + (colour p0 green) + (wood p0 teak) + (available p1) + (colour p1 black) + (treatment p1 glazed) + (available p2) + (colour p2 green) + (treatment p2 glazed) + (available p3) + (wood p3 oak) + (treatment p3 glazed) + (available p4) + (colour p4 black) + (wood p4 beech) + (surface-condition p4 smooth) + (treatment p4 glazed) + (available p5) + (surface-condition p5 smooth) + (treatment p5 glazed) + (available p6) + (colour p6 white) + (wood p6 beech) + (surface-condition p6 verysmooth) + (available p7) + (wood p7 mahogany) + (treatment p7 varnished) + (available p8) + (colour p8 blue) + (wood p8 cherry) + (surface-condition p8 verysmooth) + (available p9) + (colour p9 white) + (wood p9 beech) + (surface-condition p9 verysmooth) + (treatment p9 varnished) + (available p10) + (colour p10 green) + (wood p10 oak) + (available p11) + (wood p11 beech) + (treatment p11 glazed) + (available p12) + (colour p12 green) + (wood p12 beech) + (available p13) + (colour p13 blue) + (wood p13 oak) + (surface-condition p13 verysmooth) + (treatment p13 varnished) + (available p14) + (colour p14 mauve) + (wood p14 oak) + (surface-condition p14 verysmooth) + (available p15) + (colour p15 mauve) + (treatment p15 glazed) + (available p16) + (colour p16 mauve) + (wood p16 teak) + (surface-condition p16 smooth) + (treatment p16 varnished) + (available p17) + (colour p17 black) + (wood p17 beech) + (available p18) + (colour p18 black) + (wood p18 mahogany) + (surface-condition p18 verysmooth) + (treatment p18 glazed) + (available p19) + (surface-condition p19 verysmooth) + (treatment p19 varnished) + (available p20) + (surface-condition p20 verysmooth) + (treatment p20 glazed) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p08.pddl b/data/woodworking-sat08-strips/p08.pddl new file mode 100644 index 00000000..ecda1a5a --- /dev/null +++ b/data/woodworking-sat08-strips/p08.pddl @@ -0,0 +1,349 @@ +; woodworking task with 24 parts and 140% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 490926 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + black mauve green blue red white - acolour + beech pine mahogany walnut cherry teak - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 p18 p19 p20 p21 p22 p23 - part + b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 - board + s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (boardsize-successor s7 s8) + (boardsize-successor s8 s9) + (boardsize-successor s9 s10) + (boardsize-successor s10 s11) + (boardsize-successor s11 s12) + (has-colour glazer0 blue) + (has-colour glazer0 mauve) + (has-colour glazer0 white) + (has-colour glazer0 natural) + (has-colour glazer0 red) + (has-colour immersion-varnisher0 blue) + (has-colour immersion-varnisher0 mauve) + (has-colour immersion-varnisher0 natural) + (has-colour immersion-varnisher0 red) + (empty highspeed-saw0) + (has-colour spray-varnisher0 blue) + (has-colour spray-varnisher0 mauve) + (has-colour spray-varnisher0 natural) + (has-colour spray-varnisher0 red) + (unused p0) + (goalsize p0 large) + (= (spray-varnish-cost p0) 15) + (= (glaze-cost p0) 20) + (= (grind-cost p0) 45) + (= (plane-cost p0) 30) + (unused p1) + (goalsize p1 medium) + (= (spray-varnish-cost p1) 10) + (= (glaze-cost p1) 15) + (= (grind-cost p1) 30) + (= (plane-cost p1) 20) + (unused p2) + (goalsize p2 medium) + (= (spray-varnish-cost p2) 10) + (= (glaze-cost p2) 15) + (= (grind-cost p2) 30) + (= (plane-cost p2) 20) + (available p3) + (colour p3 green) + (wood p3 pine) + (surface-condition p3 verysmooth) + (treatment p3 varnished) + (goalsize p3 small) + (= (spray-varnish-cost p3) 5) + (= (glaze-cost p3) 10) + (= (grind-cost p3) 15) + (= (plane-cost p3) 10) + (unused p4) + (goalsize p4 large) + (= (spray-varnish-cost p4) 15) + (= (glaze-cost p4) 20) + (= (grind-cost p4) 45) + (= (plane-cost p4) 30) + (unused p5) + (goalsize p5 small) + (= (spray-varnish-cost p5) 5) + (= (glaze-cost p5) 10) + (= (grind-cost p5) 15) + (= (plane-cost p5) 10) + (unused p6) + (goalsize p6 large) + (= (spray-varnish-cost p6) 15) + (= (glaze-cost p6) 20) + (= (grind-cost p6) 45) + (= (plane-cost p6) 30) + (unused p7) + (goalsize p7 large) + (= (spray-varnish-cost p7) 15) + (= (glaze-cost p7) 20) + (= (grind-cost p7) 45) + (= (plane-cost p7) 30) + (unused p8) + (goalsize p8 large) + (= (spray-varnish-cost p8) 15) + (= (glaze-cost p8) 20) + (= (grind-cost p8) 45) + (= (plane-cost p8) 30) + (unused p9) + (goalsize p9 medium) + (= (spray-varnish-cost p9) 10) + (= (glaze-cost p9) 15) + (= (grind-cost p9) 30) + (= (plane-cost p9) 20) + (unused p10) + (goalsize p10 large) + (= (spray-varnish-cost p10) 15) + (= (glaze-cost p10) 20) + (= (grind-cost p10) 45) + (= (plane-cost p10) 30) + (unused p11) + (goalsize p11 medium) + (= (spray-varnish-cost p11) 10) + (= (glaze-cost p11) 15) + (= (grind-cost p11) 30) + (= (plane-cost p11) 20) + (unused p12) + (goalsize p12 small) + (= (spray-varnish-cost p12) 5) + (= (glaze-cost p12) 10) + (= (grind-cost p12) 15) + (= (plane-cost p12) 10) + (unused p13) + (goalsize p13 large) + (= (spray-varnish-cost p13) 15) + (= (glaze-cost p13) 20) + (= (grind-cost p13) 45) + (= (plane-cost p13) 30) + (unused p14) + (goalsize p14 small) + (= (spray-varnish-cost p14) 5) + (= (glaze-cost p14) 10) + (= (grind-cost p14) 15) + (= (plane-cost p14) 10) + (unused p15) + (goalsize p15 large) + (= (spray-varnish-cost p15) 15) + (= (glaze-cost p15) 20) + (= (grind-cost p15) 45) + (= (plane-cost p15) 30) + (available p16) + (colour p16 red) + (wood p16 teak) + (surface-condition p16 rough) + (treatment p16 varnished) + (goalsize p16 small) + (= (spray-varnish-cost p16) 5) + (= (glaze-cost p16) 10) + (= (grind-cost p16) 15) + (= (plane-cost p16) 10) + (unused p17) + (goalsize p17 large) + (= (spray-varnish-cost p17) 15) + (= (glaze-cost p17) 20) + (= (grind-cost p17) 45) + (= (plane-cost p17) 30) + (unused p18) + (goalsize p18 large) + (= (spray-varnish-cost p18) 15) + (= (glaze-cost p18) 20) + (= (grind-cost p18) 45) + (= (plane-cost p18) 30) + (unused p19) + (goalsize p19 large) + (= (spray-varnish-cost p19) 15) + (= (glaze-cost p19) 20) + (= (grind-cost p19) 45) + (= (plane-cost p19) 30) + (unused p20) + (goalsize p20 large) + (= (spray-varnish-cost p20) 15) + (= (glaze-cost p20) 20) + (= (grind-cost p20) 45) + (= (plane-cost p20) 30) + (unused p21) + (goalsize p21 large) + (= (spray-varnish-cost p21) 15) + (= (glaze-cost p21) 20) + (= (grind-cost p21) 45) + (= (plane-cost p21) 30) + (unused p22) + (goalsize p22 small) + (= (spray-varnish-cost p22) 5) + (= (glaze-cost p22) 10) + (= (grind-cost p22) 15) + (= (plane-cost p22) 10) + (unused p23) + (goalsize p23 large) + (= (spray-varnish-cost p23) 15) + (= (glaze-cost p23) 20) + (= (grind-cost p23) 45) + (= (plane-cost p23) 30) + (boardsize b0 s9) + (wood b0 cherry) + (surface-condition b0 rough) + (available b0) + (boardsize b1 s12) + (wood b1 mahogany) + (surface-condition b1 rough) + (available b1) + (boardsize b2 s7) + (wood b2 mahogany) + (surface-condition b2 smooth) + (available b2) + (boardsize b3 s9) + (wood b3 pine) + (surface-condition b3 rough) + (available b3) + (boardsize b4 s8) + (wood b4 walnut) + (surface-condition b4 rough) + (available b4) + (boardsize b5 s6) + (wood b5 walnut) + (surface-condition b5 rough) + (available b5) + (boardsize b6 s10) + (wood b6 teak) + (surface-condition b6 rough) + (available b6) + (boardsize b7 s3) + (wood b7 teak) + (surface-condition b7 rough) + (available b7) + (boardsize b8 s8) + (wood b8 beech) + (surface-condition b8 smooth) + (available b8) + (boardsize b9 s6) + (wood b9 beech) + (surface-condition b9 rough) + (available b9) + ) + (:goal + (and + (available p0) + (wood p0 cherry) + (treatment p0 varnished) + (available p1) + (colour p1 blue) + (treatment p1 glazed) + (available p2) + (wood p2 beech) + (treatment p2 varnished) + (available p3) + (colour p3 red) + (wood p3 pine) + (surface-condition p3 smooth) + (treatment p3 glazed) + (available p4) + (colour p4 red) + (wood p4 mahogany) + (surface-condition p4 verysmooth) + (treatment p4 varnished) + (available p5) + (colour p5 white) + (surface-condition p5 smooth) + (treatment p5 glazed) + (available p6) + (colour p6 natural) + (wood p6 walnut) + (surface-condition p6 verysmooth) + (treatment p6 glazed) + (available p7) + (colour p7 red) + (wood p7 beech) + (surface-condition p7 smooth) + (treatment p7 varnished) + (available p8) + (colour p8 mauve) + (wood p8 pine) + (treatment p8 varnished) + (available p9) + (colour p9 red) + (wood p9 beech) + (surface-condition p9 smooth) + (treatment p9 varnished) + (available p10) + (surface-condition p10 verysmooth) + (treatment p10 varnished) + (available p11) + (colour p11 mauve) + (surface-condition p11 smooth) + (available p12) + (colour p12 blue) + (wood p12 mahogany) + (surface-condition p12 verysmooth) + (treatment p12 varnished) + (available p13) + (colour p13 natural) + (treatment p13 glazed) + (available p14) + (colour p14 mauve) + (wood p14 beech) + (treatment p14 glazed) + (available p15) + (wood p15 pine) + (surface-condition p15 verysmooth) + (available p16) + (wood p16 teak) + (surface-condition p16 verysmooth) + (available p17) + (surface-condition p17 verysmooth) + (treatment p17 glazed) + (available p18) + (wood p18 walnut) + (treatment p18 glazed) + (available p19) + (wood p19 mahogany) + (surface-condition p19 verysmooth) + (available p20) + (wood p20 teak) + (treatment p20 varnished) + (available p21) + (wood p21 mahogany) + (surface-condition p21 verysmooth) + (available p22) + (wood p22 cherry) + (surface-condition p22 verysmooth) + (available p23) + (colour p23 natural) + (wood p23 teak) + (surface-condition p23 smooth) + (treatment p23 varnished) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p09.pddl b/data/woodworking-sat08-strips/p09.pddl new file mode 100644 index 00000000..5310c848 --- /dev/null +++ b/data/woodworking-sat08-strips/p09.pddl @@ -0,0 +1,381 @@ +; woodworking task with 27 parts and 140% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 633615 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + red green blue white black mauve - acolour + pine beech teak walnut oak mahogany cherry - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 p18 p19 p20 p21 p22 p23 p24 p25 p26 - part + b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 - board + s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (boardsize-successor s7 s8) + (boardsize-successor s8 s9) + (boardsize-successor s9 s10) + (has-colour glazer0 blue) + (has-colour glazer0 natural) + (has-colour glazer0 mauve) + (has-colour glazer0 green) + (has-colour glazer0 black) + (has-colour glazer0 white) + (has-colour glazer0 red) + (has-colour immersion-varnisher0 blue) + (has-colour immersion-varnisher0 natural) + (has-colour immersion-varnisher0 mauve) + (has-colour immersion-varnisher0 black) + (has-colour immersion-varnisher0 white) + (has-colour immersion-varnisher0 red) + (empty highspeed-saw0) + (has-colour spray-varnisher0 blue) + (has-colour spray-varnisher0 natural) + (has-colour spray-varnisher0 mauve) + (has-colour spray-varnisher0 black) + (has-colour spray-varnisher0 white) + (has-colour spray-varnisher0 red) + (unused p0) + (goalsize p0 small) + (= (spray-varnish-cost p0) 5) + (= (glaze-cost p0) 10) + (= (grind-cost p0) 15) + (= (plane-cost p0) 10) + (unused p1) + (goalsize p1 medium) + (= (spray-varnish-cost p1) 10) + (= (glaze-cost p1) 15) + (= (grind-cost p1) 30) + (= (plane-cost p1) 20) + (unused p2) + (goalsize p2 large) + (= (spray-varnish-cost p2) 15) + (= (glaze-cost p2) 20) + (= (grind-cost p2) 45) + (= (plane-cost p2) 30) + (unused p3) + (goalsize p3 medium) + (= (spray-varnish-cost p3) 10) + (= (glaze-cost p3) 15) + (= (grind-cost p3) 30) + (= (plane-cost p3) 20) + (available p4) + (colour p4 black) + (wood p4 beech) + (surface-condition p4 verysmooth) + (treatment p4 glazed) + (goalsize p4 large) + (= (spray-varnish-cost p4) 15) + (= (glaze-cost p4) 20) + (= (grind-cost p4) 45) + (= (plane-cost p4) 30) + (unused p5) + (goalsize p5 large) + (= (spray-varnish-cost p5) 15) + (= (glaze-cost p5) 20) + (= (grind-cost p5) 45) + (= (plane-cost p5) 30) + (unused p6) + (goalsize p6 large) + (= (spray-varnish-cost p6) 15) + (= (glaze-cost p6) 20) + (= (grind-cost p6) 45) + (= (plane-cost p6) 30) + (unused p7) + (goalsize p7 small) + (= (spray-varnish-cost p7) 5) + (= (glaze-cost p7) 10) + (= (grind-cost p7) 15) + (= (plane-cost p7) 10) + (unused p8) + (goalsize p8 large) + (= (spray-varnish-cost p8) 15) + (= (glaze-cost p8) 20) + (= (grind-cost p8) 45) + (= (plane-cost p8) 30) + (unused p9) + (goalsize p9 large) + (= (spray-varnish-cost p9) 15) + (= (glaze-cost p9) 20) + (= (grind-cost p9) 45) + (= (plane-cost p9) 30) + (unused p10) + (goalsize p10 large) + (= (spray-varnish-cost p10) 15) + (= (glaze-cost p10) 20) + (= (grind-cost p10) 45) + (= (plane-cost p10) 30) + (unused p11) + (goalsize p11 small) + (= (spray-varnish-cost p11) 5) + (= (glaze-cost p11) 10) + (= (grind-cost p11) 15) + (= (plane-cost p11) 10) + (unused p12) + (goalsize p12 medium) + (= (spray-varnish-cost p12) 10) + (= (glaze-cost p12) 15) + (= (grind-cost p12) 30) + (= (plane-cost p12) 20) + (unused p13) + (goalsize p13 medium) + (= (spray-varnish-cost p13) 10) + (= (glaze-cost p13) 15) + (= (grind-cost p13) 30) + (= (plane-cost p13) 20) + (unused p14) + (goalsize p14 small) + (= (spray-varnish-cost p14) 5) + (= (glaze-cost p14) 10) + (= (grind-cost p14) 15) + (= (plane-cost p14) 10) + (unused p15) + (goalsize p15 medium) + (= (spray-varnish-cost p15) 10) + (= (glaze-cost p15) 15) + (= (grind-cost p15) 30) + (= (plane-cost p15) 20) + (unused p16) + (goalsize p16 small) + (= (spray-varnish-cost p16) 5) + (= (glaze-cost p16) 10) + (= (grind-cost p16) 15) + (= (plane-cost p16) 10) + (available p17) + (colour p17 blue) + (wood p17 teak) + (surface-condition p17 smooth) + (treatment p17 varnished) + (goalsize p17 medium) + (= (spray-varnish-cost p17) 10) + (= (glaze-cost p17) 15) + (= (grind-cost p17) 30) + (= (plane-cost p17) 20) + (unused p18) + (goalsize p18 large) + (= (spray-varnish-cost p18) 15) + (= (glaze-cost p18) 20) + (= (grind-cost p18) 45) + (= (plane-cost p18) 30) + (unused p19) + (goalsize p19 large) + (= (spray-varnish-cost p19) 15) + (= (glaze-cost p19) 20) + (= (grind-cost p19) 45) + (= (plane-cost p19) 30) + (unused p20) + (goalsize p20 large) + (= (spray-varnish-cost p20) 15) + (= (glaze-cost p20) 20) + (= (grind-cost p20) 45) + (= (plane-cost p20) 30) + (unused p21) + (goalsize p21 small) + (= (spray-varnish-cost p21) 5) + (= (glaze-cost p21) 10) + (= (grind-cost p21) 15) + (= (plane-cost p21) 10) + (unused p22) + (goalsize p22 small) + (= (spray-varnish-cost p22) 5) + (= (glaze-cost p22) 10) + (= (grind-cost p22) 15) + (= (plane-cost p22) 10) + (unused p23) + (goalsize p23 small) + (= (spray-varnish-cost p23) 5) + (= (glaze-cost p23) 10) + (= (grind-cost p23) 15) + (= (plane-cost p23) 10) + (unused p24) + (goalsize p24 medium) + (= (spray-varnish-cost p24) 10) + (= (glaze-cost p24) 15) + (= (grind-cost p24) 30) + (= (plane-cost p24) 20) + (unused p25) + (goalsize p25 medium) + (= (spray-varnish-cost p25) 10) + (= (glaze-cost p25) 15) + (= (grind-cost p25) 30) + (= (plane-cost p25) 20) + (unused p26) + (goalsize p26 medium) + (= (spray-varnish-cost p26) 10) + (= (glaze-cost p26) 15) + (= (grind-cost p26) 30) + (= (plane-cost p26) 20) + (boardsize b0 s6) + (wood b0 cherry) + (surface-condition b0 rough) + (available b0) + (boardsize b1 s10) + (wood b1 mahogany) + (surface-condition b1 rough) + (available b1) + (boardsize b2 s7) + (wood b2 mahogany) + (surface-condition b2 rough) + (available b2) + (boardsize b3 s5) + (wood b3 oak) + (surface-condition b3 rough) + (available b3) + (boardsize b4 s2) + (wood b4 oak) + (surface-condition b4 rough) + (available b4) + (boardsize b5 s10) + (wood b5 pine) + (surface-condition b5 smooth) + (available b5) + (boardsize b6 s6) + (wood b6 pine) + (surface-condition b6 rough) + (available b6) + (boardsize b7 s7) + (wood b7 walnut) + (surface-condition b7 smooth) + (available b7) + (boardsize b8 s7) + (wood b8 teak) + (surface-condition b8 rough) + (available b8) + (boardsize b9 s9) + (wood b9 beech) + (surface-condition b9 rough) + (available b9) + (boardsize b10 s4) + (wood b10 beech) + (surface-condition b10 smooth) + (available b10) + ) + (:goal + (and + (available p0) + (colour p0 mauve) + (treatment p0 varnished) + (available p1) + (colour p1 mauve) + (surface-condition p1 smooth) + (available p2) + (wood p2 mahogany) + (surface-condition p2 smooth) + (available p3) + (colour p3 black) + (wood p3 teak) + (surface-condition p3 smooth) + (treatment p3 varnished) + (available p4) + (colour p4 green) + (wood p4 beech) + (surface-condition p4 smooth) + (treatment p4 glazed) + (available p5) + (colour p5 black) + (wood p5 walnut) + (surface-condition p5 smooth) + (treatment p5 varnished) + (available p6) + (colour p6 natural) + (wood p6 pine) + (surface-condition p6 smooth) + (treatment p6 varnished) + (available p7) + (surface-condition p7 verysmooth) + (treatment p7 varnished) + (available p8) + (colour p8 blue) + (wood p8 beech) + (available p9) + (colour p9 mauve) + (wood p9 pine) + (surface-condition p9 verysmooth) + (treatment p9 varnished) + (available p10) + (wood p10 pine) + (treatment p10 glazed) + (available p11) + (wood p11 mahogany) + (treatment p11 glazed) + (available p12) + (colour p12 blue) + (wood p12 oak) + (available p13) + (colour p13 mauve) + (surface-condition p13 verysmooth) + (available p14) + (colour p14 natural) + (surface-condition p14 verysmooth) + (available p15) + (colour p15 blue) + (surface-condition p15 smooth) + (available p16) + (colour p16 natural) + (surface-condition p16 smooth) + (treatment p16 varnished) + (available p17) + (colour p17 white) + (wood p17 teak) + (treatment p17 varnished) + (available p18) + (wood p18 mahogany) + (treatment p18 glazed) + (available p19) + (wood p19 mahogany) + (surface-condition p19 verysmooth) + (available p20) + (colour p20 blue) + (treatment p20 varnished) + (available p21) + (colour p21 red) + (wood p21 oak) + (available p22) + (colour p22 black) + (wood p22 oak) + (surface-condition p22 smooth) + (treatment p22 glazed) + (available p23) + (colour p23 white) + (surface-condition p23 verysmooth) + (available p24) + (wood p24 pine) + (surface-condition p24 verysmooth) + (available p25) + (wood p25 cherry) + (treatment p25 varnished) + (available p26) + (colour p26 mauve) + (surface-condition p26 verysmooth) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p10.pddl b/data/woodworking-sat08-strips/p10.pddl new file mode 100644 index 00000000..6f63b3ea --- /dev/null +++ b/data/woodworking-sat08-strips/p10.pddl @@ -0,0 +1,426 @@ +; woodworking task with 30 parts and 140% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 747708 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + black mauve white green blue red - acolour + teak beech cherry walnut pine mahogany oak - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 p18 p19 p20 p21 p22 p23 p24 p25 p26 p27 p28 p29 - part + b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 - board + s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (boardsize-successor s7 s8) + (boardsize-successor s8 s9) + (boardsize-successor s9 s10) + (has-colour glazer0 blue) + (has-colour glazer0 natural) + (has-colour glazer0 mauve) + (has-colour glazer0 green) + (has-colour glazer0 black) + (has-colour glazer0 white) + (has-colour glazer0 red) + (has-colour immersion-varnisher0 blue) + (has-colour immersion-varnisher0 natural) + (has-colour immersion-varnisher0 mauve) + (has-colour immersion-varnisher0 black) + (has-colour immersion-varnisher0 white) + (has-colour immersion-varnisher0 red) + (empty highspeed-saw0) + (has-colour spray-varnisher0 blue) + (has-colour spray-varnisher0 natural) + (has-colour spray-varnisher0 mauve) + (has-colour spray-varnisher0 black) + (has-colour spray-varnisher0 white) + (has-colour spray-varnisher0 red) + (unused p0) + (goalsize p0 large) + (= (spray-varnish-cost p0) 15) + (= (glaze-cost p0) 20) + (= (grind-cost p0) 45) + (= (plane-cost p0) 30) + (unused p1) + (goalsize p1 medium) + (= (spray-varnish-cost p1) 10) + (= (glaze-cost p1) 15) + (= (grind-cost p1) 30) + (= (plane-cost p1) 20) + (unused p2) + (goalsize p2 small) + (= (spray-varnish-cost p2) 5) + (= (glaze-cost p2) 10) + (= (grind-cost p2) 15) + (= (plane-cost p2) 10) + (unused p3) + (goalsize p3 large) + (= (spray-varnish-cost p3) 15) + (= (glaze-cost p3) 20) + (= (grind-cost p3) 45) + (= (plane-cost p3) 30) + (available p4) + (colour p4 blue) + (wood p4 oak) + (surface-condition p4 smooth) + (treatment p4 colourfragments) + (goalsize p4 large) + (= (spray-varnish-cost p4) 15) + (= (glaze-cost p4) 20) + (= (grind-cost p4) 45) + (= (plane-cost p4) 30) + (unused p5) + (goalsize p5 small) + (= (spray-varnish-cost p5) 5) + (= (glaze-cost p5) 10) + (= (grind-cost p5) 15) + (= (plane-cost p5) 10) + (unused p6) + (goalsize p6 large) + (= (spray-varnish-cost p6) 15) + (= (glaze-cost p6) 20) + (= (grind-cost p6) 45) + (= (plane-cost p6) 30) + (unused p7) + (goalsize p7 large) + (= (spray-varnish-cost p7) 15) + (= (glaze-cost p7) 20) + (= (grind-cost p7) 45) + (= (plane-cost p7) 30) + (unused p8) + (goalsize p8 large) + (= (spray-varnish-cost p8) 15) + (= (glaze-cost p8) 20) + (= (grind-cost p8) 45) + (= (plane-cost p8) 30) + (unused p9) + (goalsize p9 medium) + (= (spray-varnish-cost p9) 10) + (= (glaze-cost p9) 15) + (= (grind-cost p9) 30) + (= (plane-cost p9) 20) + (unused p10) + (goalsize p10 large) + (= (spray-varnish-cost p10) 15) + (= (glaze-cost p10) 20) + (= (grind-cost p10) 45) + (= (plane-cost p10) 30) + (unused p11) + (goalsize p11 small) + (= (spray-varnish-cost p11) 5) + (= (glaze-cost p11) 10) + (= (grind-cost p11) 15) + (= (plane-cost p11) 10) + (unused p12) + (goalsize p12 medium) + (= (spray-varnish-cost p12) 10) + (= (glaze-cost p12) 15) + (= (grind-cost p12) 30) + (= (plane-cost p12) 20) + (unused p13) + (goalsize p13 large) + (= (spray-varnish-cost p13) 15) + (= (glaze-cost p13) 20) + (= (grind-cost p13) 45) + (= (plane-cost p13) 30) + (unused p14) + (goalsize p14 medium) + (= (spray-varnish-cost p14) 10) + (= (glaze-cost p14) 15) + (= (grind-cost p14) 30) + (= (plane-cost p14) 20) + (unused p15) + (goalsize p15 medium) + (= (spray-varnish-cost p15) 10) + (= (glaze-cost p15) 15) + (= (grind-cost p15) 30) + (= (plane-cost p15) 20) + (available p16) + (colour p16 green) + (wood p16 beech) + (surface-condition p16 verysmooth) + (treatment p16 varnished) + (goalsize p16 small) + (= (spray-varnish-cost p16) 5) + (= (glaze-cost p16) 10) + (= (grind-cost p16) 15) + (= (plane-cost p16) 10) + (unused p17) + (goalsize p17 medium) + (= (spray-varnish-cost p17) 10) + (= (glaze-cost p17) 15) + (= (grind-cost p17) 30) + (= (plane-cost p17) 20) + (available p18) + (colour p18 natural) + (wood p18 mahogany) + (surface-condition p18 smooth) + (treatment p18 glazed) + (goalsize p18 small) + (= (spray-varnish-cost p18) 5) + (= (glaze-cost p18) 10) + (= (grind-cost p18) 15) + (= (plane-cost p18) 10) + (available p19) + (colour p19 red) + (wood p19 walnut) + (surface-condition p19 verysmooth) + (treatment p19 varnished) + (goalsize p19 small) + (= (spray-varnish-cost p19) 5) + (= (glaze-cost p19) 10) + (= (grind-cost p19) 15) + (= (plane-cost p19) 10) + (unused p20) + (goalsize p20 medium) + (= (spray-varnish-cost p20) 10) + (= (glaze-cost p20) 15) + (= (grind-cost p20) 30) + (= (plane-cost p20) 20) + (unused p21) + (goalsize p21 small) + (= (spray-varnish-cost p21) 5) + (= (glaze-cost p21) 10) + (= (grind-cost p21) 15) + (= (plane-cost p21) 10) + (unused p22) + (goalsize p22 small) + (= (spray-varnish-cost p22) 5) + (= (glaze-cost p22) 10) + (= (grind-cost p22) 15) + (= (plane-cost p22) 10) + (unused p23) + (goalsize p23 small) + (= (spray-varnish-cost p23) 5) + (= (glaze-cost p23) 10) + (= (grind-cost p23) 15) + (= (plane-cost p23) 10) + (unused p24) + (goalsize p24 small) + (= (spray-varnish-cost p24) 5) + (= (glaze-cost p24) 10) + (= (grind-cost p24) 15) + (= (plane-cost p24) 10) + (available p25) + (colour p25 mauve) + (wood p25 cherry) + (surface-condition p25 rough) + (treatment p25 varnished) + (goalsize p25 small) + (= (spray-varnish-cost p25) 5) + (= (glaze-cost p25) 10) + (= (grind-cost p25) 15) + (= (plane-cost p25) 10) + (unused p26) + (goalsize p26 large) + (= (spray-varnish-cost p26) 15) + (= (glaze-cost p26) 20) + (= (grind-cost p26) 45) + (= (plane-cost p26) 30) + (unused p27) + (goalsize p27 medium) + (= (spray-varnish-cost p27) 10) + (= (glaze-cost p27) 15) + (= (grind-cost p27) 30) + (= (plane-cost p27) 20) + (unused p28) + (goalsize p28 small) + (= (spray-varnish-cost p28) 5) + (= (glaze-cost p28) 10) + (= (grind-cost p28) 15) + (= (plane-cost p28) 10) + (unused p29) + (goalsize p29 medium) + (= (spray-varnish-cost p29) 10) + (= (glaze-cost p29) 15) + (= (grind-cost p29) 30) + (= (plane-cost p29) 20) + (boardsize b0 s10) + (wood b0 cherry) + (surface-condition b0 rough) + (available b0) + (boardsize b1 s4) + (wood b1 cherry) + (surface-condition b1 rough) + (available b1) + (boardsize b2 s7) + (wood b2 mahogany) + (surface-condition b2 rough) + (available b2) + (boardsize b3 s6) + (wood b3 oak) + (surface-condition b3 rough) + (available b3) + (boardsize b4 s8) + (wood b4 oak) + (surface-condition b4 rough) + (available b4) + (boardsize b5 s6) + (wood b5 oak) + (surface-condition b5 smooth) + (available b5) + (boardsize b6 s9) + (wood b6 pine) + (surface-condition b6 smooth) + (available b6) + (boardsize b7 s3) + (wood b7 teak) + (surface-condition b7 smooth) + (available b7) + (boardsize b8 s10) + (wood b8 beech) + (surface-condition b8 rough) + (available b8) + (boardsize b9 s8) + (wood b9 beech) + (surface-condition b9 rough) + (available b9) + (boardsize b10 s1) + (wood b10 beech) + (surface-condition b10 rough) + (available b10) + ) + (:goal + (and + (available p0) + (colour p0 black) + (treatment p0 glazed) + (available p1) + (colour p1 mauve) + (wood p1 oak) + (treatment p1 glazed) + (available p2) + (surface-condition p2 verysmooth) + (treatment p2 glazed) + (available p3) + (colour p3 white) + (surface-condition p3 verysmooth) + (available p4) + (wood p4 oak) + (surface-condition p4 verysmooth) + (treatment p4 glazed) + (available p5) + (colour p5 green) + (wood p5 oak) + (surface-condition p5 verysmooth) + (treatment p5 glazed) + (available p6) + (colour p6 black) + (wood p6 cherry) + (surface-condition p6 smooth) + (treatment p6 varnished) + (available p7) + (colour p7 natural) + (wood p7 mahogany) + (surface-condition p7 smooth) + (treatment p7 varnished) + (available p8) + (colour p8 natural) + (wood p8 beech) + (available p9) + (surface-condition p9 smooth) + (treatment p9 varnished) + (available p10) + (surface-condition p10 verysmooth) + (treatment p10 varnished) + (available p11) + (colour p11 mauve) + (surface-condition p11 smooth) + (available p12) + (colour p12 blue) + (wood p12 oak) + (surface-condition p12 smooth) + (treatment p12 varnished) + (available p13) + (colour p13 black) + (surface-condition p13 verysmooth) + (available p14) + (colour p14 natural) + (treatment p14 varnished) + (available p15) + (wood p15 beech) + (treatment p15 varnished) + (available p16) + (colour p16 red) + (surface-condition p16 smooth) + (available p17) + (colour p17 black) + (wood p17 oak) + (surface-condition p17 smooth) + (available p18) + (wood p18 mahogany) + (surface-condition p18 smooth) + (treatment p18 varnished) + (available p19) + (colour p19 natural) + (surface-condition p19 verysmooth) + (treatment p19 glazed) + (available p20) + (wood p20 pine) + (treatment p20 glazed) + (available p21) + (colour p21 red) + (wood p21 beech) + (surface-condition p21 verysmooth) + (treatment p21 glazed) + (available p22) + (colour p22 blue) + (surface-condition p22 smooth) + (treatment p22 glazed) + (available p23) + (colour p23 black) + (wood p23 pine) + (surface-condition p23 verysmooth) + (available p24) + (colour p24 black) + (treatment p24 glazed) + (available p25) + (colour p25 green) + (treatment p25 glazed) + (available p26) + (colour p26 natural) + (treatment p26 glazed) + (available p27) + (colour p27 green) + (treatment p27 glazed) + (available p28) + (colour p28 mauve) + (surface-condition p28 verysmooth) + (treatment p28 varnished) + (available p29) + (colour p29 black) + (wood p29 cherry) + (surface-condition p29 verysmooth) + (treatment p29 glazed) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p11.pddl b/data/woodworking-sat08-strips/p11.pddl new file mode 100644 index 00000000..21d602b9 --- /dev/null +++ b/data/woodworking-sat08-strips/p11.pddl @@ -0,0 +1,85 @@ +; woodworking task with 3 parts and 120% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 578239 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + blue mauve - acolour + beech mahogany - awood + p0 p1 p2 - part + - board + s0 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (has-colour glazer0 natural) + (has-colour immersion-varnisher0 blue) + (empty highspeed-saw0) + (has-colour spray-varnisher0 mauve) + (available p0) + (colour p0 blue) + (wood p0 mahogany) + (surface-condition p0 verysmooth) + (treatment p0 colourfragments) + (goalsize p0 small) + (= (spray-varnish-cost p0) 5) + (= (glaze-cost p0) 10) + (= (grind-cost p0) 15) + (= (plane-cost p0) 10) + (available p1) + (colour p1 natural) + (wood p1 mahogany) + (surface-condition p1 smooth) + (treatment p1 colourfragments) + (goalsize p1 small) + (= (spray-varnish-cost p1) 5) + (= (glaze-cost p1) 10) + (= (grind-cost p1) 15) + (= (plane-cost p1) 10) + (available p2) + (colour p2 mauve) + (wood p2 beech) + (surface-condition p2 verysmooth) + (treatment p2 colourfragments) + (goalsize p2 small) + (= (spray-varnish-cost p2) 5) + (= (glaze-cost p2) 10) + (= (grind-cost p2) 15) + (= (plane-cost p2) 10) + ) + (:goal + (and + (available p0) + (wood p0 mahogany) + (surface-condition p0 smooth) + (available p1) + (surface-condition p1 smooth) + (treatment p1 glazed) + (available p2) + (colour p2 natural) + (treatment p2 glazed) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p12.pddl b/data/woodworking-sat08-strips/p12.pddl new file mode 100644 index 00000000..a46b37c8 --- /dev/null +++ b/data/woodworking-sat08-strips/p12.pddl @@ -0,0 +1,126 @@ +; woodworking task with 6 parts and 120% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 920484 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + black blue mauve green - acolour + cherry pine - awood + p0 p1 p2 p3 p4 p5 - part + b0 b1 - board + s0 s1 s2 s3 s4 s5 s6 s7 s8 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (boardsize-successor s7 s8) + (has-colour glazer0 black) + (has-colour immersion-varnisher0 blue) + (empty highspeed-saw0) + (has-colour spray-varnisher0 blue) + (available p0) + (colour p0 black) + (wood p0 cherry) + (surface-condition p0 rough) + (treatment p0 glazed) + (goalsize p0 small) + (= (spray-varnish-cost p0) 5) + (= (glaze-cost p0) 10) + (= (grind-cost p0) 15) + (= (plane-cost p0) 10) + (unused p1) + (goalsize p1 large) + (= (spray-varnish-cost p1) 15) + (= (glaze-cost p1) 20) + (= (grind-cost p1) 45) + (= (plane-cost p1) 30) + (unused p2) + (goalsize p2 large) + (= (spray-varnish-cost p2) 15) + (= (glaze-cost p2) 20) + (= (grind-cost p2) 45) + (= (plane-cost p2) 30) + (unused p3) + (goalsize p3 small) + (= (spray-varnish-cost p3) 5) + (= (glaze-cost p3) 10) + (= (grind-cost p3) 15) + (= (plane-cost p3) 10) + (unused p4) + (goalsize p4 large) + (= (spray-varnish-cost p4) 15) + (= (glaze-cost p4) 20) + (= (grind-cost p4) 45) + (= (plane-cost p4) 30) + (available p5) + (colour p5 mauve) + (wood p5 cherry) + (surface-condition p5 rough) + (treatment p5 colourfragments) + (goalsize p5 medium) + (= (spray-varnish-cost p5) 10) + (= (glaze-cost p5) 15) + (= (grind-cost p5) 30) + (= (plane-cost p5) 20) + (boardsize b0 s5) + (wood b0 cherry) + (surface-condition b0 rough) + (available b0) + (boardsize b1 s8) + (wood b1 pine) + (surface-condition b1 smooth) + (available b1) + ) + (:goal + (and + (available p0) + (surface-condition p0 verysmooth) + (treatment p0 varnished) + (available p1) + (wood p1 pine) + (surface-condition p1 smooth) + (available p2) + (colour p2 blue) + (wood p2 pine) + (surface-condition p2 verysmooth) + (treatment p2 varnished) + (available p3) + (wood p3 cherry) + (surface-condition p3 smooth) + (available p4) + (wood p4 cherry) + (surface-condition p4 verysmooth) + (available p5) + (wood p5 cherry) + (surface-condition p5 smooth) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p13.pddl b/data/woodworking-sat08-strips/p13.pddl new file mode 100644 index 00000000..2b00e854 --- /dev/null +++ b/data/woodworking-sat08-strips/p13.pddl @@ -0,0 +1,161 @@ +; woodworking task with 9 parts and 120% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 958211 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + green mauve blue red black white - acolour + cherry mahogany - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 - part + b0 b1 b2 - board + s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (boardsize-successor s7 s8) + (boardsize-successor s8 s9) + (has-colour glazer0 blue) + (has-colour glazer0 white) + (has-colour immersion-varnisher0 blue) + (has-colour immersion-varnisher0 white) + (has-colour immersion-varnisher0 black) + (has-colour immersion-varnisher0 red) + (empty highspeed-saw0) + (has-colour spray-varnisher0 blue) + (has-colour spray-varnisher0 white) + (has-colour spray-varnisher0 black) + (has-colour spray-varnisher0 red) + (unused p0) + (goalsize p0 large) + (= (spray-varnish-cost p0) 15) + (= (glaze-cost p0) 20) + (= (grind-cost p0) 45) + (= (plane-cost p0) 30) + (unused p1) + (goalsize p1 medium) + (= (spray-varnish-cost p1) 10) + (= (glaze-cost p1) 15) + (= (grind-cost p1) 30) + (= (plane-cost p1) 20) + (unused p2) + (goalsize p2 small) + (= (spray-varnish-cost p2) 5) + (= (glaze-cost p2) 10) + (= (grind-cost p2) 15) + (= (plane-cost p2) 10) + (unused p3) + (goalsize p3 medium) + (= (spray-varnish-cost p3) 10) + (= (glaze-cost p3) 15) + (= (grind-cost p3) 30) + (= (plane-cost p3) 20) + (unused p4) + (goalsize p4 small) + (= (spray-varnish-cost p4) 5) + (= (glaze-cost p4) 10) + (= (grind-cost p4) 15) + (= (plane-cost p4) 10) + (unused p5) + (goalsize p5 small) + (= (spray-varnish-cost p5) 5) + (= (glaze-cost p5) 10) + (= (grind-cost p5) 15) + (= (plane-cost p5) 10) + (unused p6) + (goalsize p6 medium) + (= (spray-varnish-cost p6) 10) + (= (glaze-cost p6) 15) + (= (grind-cost p6) 30) + (= (plane-cost p6) 20) + (unused p7) + (goalsize p7 large) + (= (spray-varnish-cost p7) 15) + (= (glaze-cost p7) 20) + (= (grind-cost p7) 45) + (= (plane-cost p7) 30) + (unused p8) + (goalsize p8 large) + (= (spray-varnish-cost p8) 15) + (= (glaze-cost p8) 20) + (= (grind-cost p8) 45) + (= (plane-cost p8) 30) + (boardsize b0 s9) + (wood b0 cherry) + (surface-condition b0 rough) + (available b0) + (boardsize b1 s7) + (wood b1 mahogany) + (surface-condition b1 rough) + (available b1) + (boardsize b2 s7) + (wood b2 mahogany) + (surface-condition b2 rough) + (available b2) + ) + (:goal + (and + (available p0) + (colour p0 red) + (wood p0 cherry) + (surface-condition p0 verysmooth) + (treatment p0 varnished) + (available p1) + (colour p1 blue) + (surface-condition p1 verysmooth) + (available p2) + (colour p2 white) + (wood p2 cherry) + (surface-condition p2 smooth) + (treatment p2 varnished) + (available p3) + (surface-condition p3 smooth) + (treatment p3 glazed) + (available p4) + (colour p4 black) + (wood p4 mahogany) + (surface-condition p4 smooth) + (treatment p4 varnished) + (available p5) + (colour p5 white) + (wood p5 mahogany) + (available p6) + (colour p6 white) + (treatment p6 glazed) + (available p7) + (wood p7 cherry) + (surface-condition p7 smooth) + (available p8) + (wood p8 mahogany) + (treatment p8 glazed) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p14.pddl b/data/woodworking-sat08-strips/p14.pddl new file mode 100644 index 00000000..076b70e9 --- /dev/null +++ b/data/woodworking-sat08-strips/p14.pddl @@ -0,0 +1,205 @@ +; woodworking task with 12 parts and 120% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 48592 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + green blue red mauve white black - acolour + beech teak cherry - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 - part + b0 b1 b2 b3 b4 - board + s0 s1 s2 s3 s4 s5 s6 s7 s8 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (boardsize-successor s7 s8) + (has-colour glazer0 blue) + (has-colour glazer0 natural) + (has-colour glazer0 white) + (has-colour glazer0 green) + (has-colour glazer0 red) + (has-colour immersion-varnisher0 blue) + (has-colour immersion-varnisher0 natural) + (has-colour immersion-varnisher0 green) + (has-colour immersion-varnisher0 black) + (has-colour immersion-varnisher0 white) + (has-colour immersion-varnisher0 red) + (empty highspeed-saw0) + (has-colour spray-varnisher0 blue) + (has-colour spray-varnisher0 natural) + (has-colour spray-varnisher0 green) + (has-colour spray-varnisher0 black) + (has-colour spray-varnisher0 white) + (has-colour spray-varnisher0 red) + (unused p0) + (goalsize p0 small) + (= (spray-varnish-cost p0) 5) + (= (glaze-cost p0) 10) + (= (grind-cost p0) 15) + (= (plane-cost p0) 10) + (available p1) + (colour p1 blue) + (wood p1 beech) + (surface-condition p1 smooth) + (treatment p1 glazed) + (goalsize p1 small) + (= (spray-varnish-cost p1) 5) + (= (glaze-cost p1) 10) + (= (grind-cost p1) 15) + (= (plane-cost p1) 10) + (unused p2) + (goalsize p2 large) + (= (spray-varnish-cost p2) 15) + (= (glaze-cost p2) 20) + (= (grind-cost p2) 45) + (= (plane-cost p2) 30) + (unused p3) + (goalsize p3 small) + (= (spray-varnish-cost p3) 5) + (= (glaze-cost p3) 10) + (= (grind-cost p3) 15) + (= (plane-cost p3) 10) + (unused p4) + (goalsize p4 medium) + (= (spray-varnish-cost p4) 10) + (= (glaze-cost p4) 15) + (= (grind-cost p4) 30) + (= (plane-cost p4) 20) + (unused p5) + (goalsize p5 medium) + (= (spray-varnish-cost p5) 10) + (= (glaze-cost p5) 15) + (= (grind-cost p5) 30) + (= (plane-cost p5) 20) + (unused p6) + (goalsize p6 large) + (= (spray-varnish-cost p6) 15) + (= (glaze-cost p6) 20) + (= (grind-cost p6) 45) + (= (plane-cost p6) 30) + (unused p7) + (goalsize p7 large) + (= (spray-varnish-cost p7) 15) + (= (glaze-cost p7) 20) + (= (grind-cost p7) 45) + (= (plane-cost p7) 30) + (unused p8) + (goalsize p8 large) + (= (spray-varnish-cost p8) 15) + (= (glaze-cost p8) 20) + (= (grind-cost p8) 45) + (= (plane-cost p8) 30) + (unused p9) + (goalsize p9 small) + (= (spray-varnish-cost p9) 5) + (= (glaze-cost p9) 10) + (= (grind-cost p9) 15) + (= (plane-cost p9) 10) + (unused p10) + (goalsize p10 medium) + (= (spray-varnish-cost p10) 10) + (= (glaze-cost p10) 15) + (= (grind-cost p10) 30) + (= (plane-cost p10) 20) + (unused p11) + (goalsize p11 medium) + (= (spray-varnish-cost p11) 10) + (= (glaze-cost p11) 15) + (= (grind-cost p11) 30) + (= (plane-cost p11) 20) + (boardsize b0 s6) + (wood b0 beech) + (surface-condition b0 smooth) + (available b0) + (boardsize b1 s6) + (wood b1 beech) + (surface-condition b1 rough) + (available b1) + (boardsize b2 s8) + (wood b2 cherry) + (surface-condition b2 rough) + (available b2) + (boardsize b3 s3) + (wood b3 cherry) + (surface-condition b3 smooth) + (available b3) + (boardsize b4 s5) + (wood b4 teak) + (surface-condition b4 rough) + (available b4) + ) + (:goal + (and + (available p0) + (wood p0 cherry) + (surface-condition p0 verysmooth) + (available p1) + (colour p1 white) + (surface-condition p1 verysmooth) + (available p2) + (wood p2 beech) + (surface-condition p2 smooth) + (available p3) + (colour p3 blue) + (wood p3 beech) + (surface-condition p3 smooth) + (treatment p3 varnished) + (available p4) + (colour p4 black) + (wood p4 teak) + (treatment p4 varnished) + (available p5) + (colour p5 blue) + (wood p5 beech) + (available p6) + (colour p6 natural) + (surface-condition p6 verysmooth) + (available p7) + (colour p7 white) + (wood p7 beech) + (surface-condition p7 verysmooth) + (treatment p7 glazed) + (available p8) + (colour p8 red) + (surface-condition p8 smooth) + (available p9) + (colour p9 red) + (surface-condition p9 verysmooth) + (available p10) + (colour p10 green) + (wood p10 cherry) + (available p11) + (surface-condition p11 verysmooth) + (treatment p11 glazed) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p15.pddl b/data/woodworking-sat08-strips/p15.pddl new file mode 100644 index 00000000..431ace50 --- /dev/null +++ b/data/woodworking-sat08-strips/p15.pddl @@ -0,0 +1,234 @@ +; woodworking task with 15 parts and 120% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 370706 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + mauve white blue black red green - acolour + oak mahogany teak beech - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 - part + b0 b1 b2 b3 b4 - board + s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (boardsize-successor s7 s8) + (boardsize-successor s8 s9) + (boardsize-successor s9 s10) + (boardsize-successor s10 s11) + (has-colour glazer0 blue) + (has-colour glazer0 white) + (has-colour glazer0 red) + (has-colour immersion-varnisher0 blue) + (has-colour immersion-varnisher0 white) + (empty highspeed-saw0) + (has-colour spray-varnisher0 blue) + (has-colour spray-varnisher0 white) + (unused p0) + (goalsize p0 large) + (= (spray-varnish-cost p0) 15) + (= (glaze-cost p0) 20) + (= (grind-cost p0) 45) + (= (plane-cost p0) 30) + (unused p1) + (goalsize p1 large) + (= (spray-varnish-cost p1) 15) + (= (glaze-cost p1) 20) + (= (grind-cost p1) 45) + (= (plane-cost p1) 30) + (unused p2) + (goalsize p2 small) + (= (spray-varnish-cost p2) 5) + (= (glaze-cost p2) 10) + (= (grind-cost p2) 15) + (= (plane-cost p2) 10) + (available p3) + (colour p3 green) + (wood p3 beech) + (surface-condition p3 verysmooth) + (treatment p3 varnished) + (goalsize p3 large) + (= (spray-varnish-cost p3) 15) + (= (glaze-cost p3) 20) + (= (grind-cost p3) 45) + (= (plane-cost p3) 30) + (unused p4) + (goalsize p4 medium) + (= (spray-varnish-cost p4) 10) + (= (glaze-cost p4) 15) + (= (grind-cost p4) 30) + (= (plane-cost p4) 20) + (unused p5) + (goalsize p5 large) + (= (spray-varnish-cost p5) 15) + (= (glaze-cost p5) 20) + (= (grind-cost p5) 45) + (= (plane-cost p5) 30) + (unused p6) + (goalsize p6 large) + (= (spray-varnish-cost p6) 15) + (= (glaze-cost p6) 20) + (= (grind-cost p6) 45) + (= (plane-cost p6) 30) + (unused p7) + (goalsize p7 large) + (= (spray-varnish-cost p7) 15) + (= (glaze-cost p7) 20) + (= (grind-cost p7) 45) + (= (plane-cost p7) 30) + (unused p8) + (goalsize p8 large) + (= (spray-varnish-cost p8) 15) + (= (glaze-cost p8) 20) + (= (grind-cost p8) 45) + (= (plane-cost p8) 30) + (unused p9) + (goalsize p9 medium) + (= (spray-varnish-cost p9) 10) + (= (glaze-cost p9) 15) + (= (grind-cost p9) 30) + (= (plane-cost p9) 20) + (unused p10) + (goalsize p10 large) + (= (spray-varnish-cost p10) 15) + (= (glaze-cost p10) 20) + (= (grind-cost p10) 45) + (= (plane-cost p10) 30) + (unused p11) + (goalsize p11 small) + (= (spray-varnish-cost p11) 5) + (= (glaze-cost p11) 10) + (= (grind-cost p11) 15) + (= (plane-cost p11) 10) + (unused p12) + (goalsize p12 large) + (= (spray-varnish-cost p12) 15) + (= (glaze-cost p12) 20) + (= (grind-cost p12) 45) + (= (plane-cost p12) 30) + (available p13) + (colour p13 red) + (wood p13 beech) + (surface-condition p13 rough) + (treatment p13 glazed) + (goalsize p13 medium) + (= (spray-varnish-cost p13) 10) + (= (glaze-cost p13) 15) + (= (grind-cost p13) 30) + (= (plane-cost p13) 20) + (available p14) + (colour p14 green) + (wood p14 teak) + (surface-condition p14 rough) + (treatment p14 colourfragments) + (goalsize p14 small) + (= (spray-varnish-cost p14) 5) + (= (glaze-cost p14) 10) + (= (grind-cost p14) 15) + (= (plane-cost p14) 10) + (boardsize b0 s10) + (wood b0 beech) + (surface-condition b0 rough) + (available b0) + (boardsize b1 s5) + (wood b1 teak) + (surface-condition b1 rough) + (available b1) + (boardsize b2 s9) + (wood b2 mahogany) + (surface-condition b2 rough) + (available b2) + (boardsize b3 s11) + (wood b3 oak) + (surface-condition b3 rough) + (available b3) + (boardsize b4 s3) + (wood b4 oak) + (surface-condition b4 rough) + (available b4) + ) + (:goal + (and + (available p0) + (colour p0 white) + (treatment p0 glazed) + (available p1) + (wood p1 mahogany) + (surface-condition p1 verysmooth) + (available p2) + (surface-condition p2 smooth) + (treatment p2 varnished) + (available p3) + (colour p3 red) + (treatment p3 glazed) + (available p4) + (colour p4 blue) + (surface-condition p4 verysmooth) + (treatment p4 varnished) + (available p5) + (surface-condition p5 smooth) + (treatment p5 varnished) + (available p6) + (surface-condition p6 smooth) + (treatment p6 glazed) + (available p7) + (wood p7 mahogany) + (treatment p7 varnished) + (available p8) + (colour p8 red) + (wood p8 beech) + (surface-condition p8 smooth) + (treatment p8 glazed) + (available p9) + (wood p9 oak) + (surface-condition p9 smooth) + (available p10) + (wood p10 oak) + (surface-condition p10 verysmooth) + (available p11) + (colour p11 white) + (wood p11 mahogany) + (surface-condition p11 smooth) + (treatment p11 varnished) + (available p12) + (wood p12 oak) + (surface-condition p12 smooth) + (available p13) + (colour p13 blue) + (wood p13 beech) + (treatment p13 glazed) + (available p14) + (surface-condition p14 smooth) + (treatment p14 glazed) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p16.pddl b/data/woodworking-sat08-strips/p16.pddl new file mode 100644 index 00000000..8e1a5bc4 --- /dev/null +++ b/data/woodworking-sat08-strips/p16.pddl @@ -0,0 +1,281 @@ +; woodworking task with 18 parts and 120% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 68491 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + red green mauve black blue white - acolour + walnut teak cherry beech oak - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 - part + b0 b1 b2 b3 b4 b5 b6 - board + s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (boardsize-successor s7 s8) + (boardsize-successor s8 s9) + (has-colour glazer0 blue) + (has-colour glazer0 green) + (has-colour glazer0 white) + (has-colour glazer0 natural) + (has-colour glazer0 mauve) + (has-colour immersion-varnisher0 blue) + (has-colour immersion-varnisher0 natural) + (has-colour immersion-varnisher0 mauve) + (has-colour immersion-varnisher0 black) + (has-colour immersion-varnisher0 green) + (has-colour immersion-varnisher0 white) + (empty highspeed-saw0) + (has-colour spray-varnisher0 blue) + (has-colour spray-varnisher0 natural) + (has-colour spray-varnisher0 mauve) + (has-colour spray-varnisher0 black) + (has-colour spray-varnisher0 green) + (has-colour spray-varnisher0 white) + (unused p0) + (goalsize p0 large) + (= (spray-varnish-cost p0) 15) + (= (glaze-cost p0) 20) + (= (grind-cost p0) 45) + (= (plane-cost p0) 30) + (unused p1) + (goalsize p1 small) + (= (spray-varnish-cost p1) 5) + (= (glaze-cost p1) 10) + (= (grind-cost p1) 15) + (= (plane-cost p1) 10) + (available p2) + (colour p2 mauve) + (wood p2 oak) + (surface-condition p2 rough) + (treatment p2 glazed) + (goalsize p2 small) + (= (spray-varnish-cost p2) 5) + (= (glaze-cost p2) 10) + (= (grind-cost p2) 15) + (= (plane-cost p2) 10) + (unused p3) + (goalsize p3 large) + (= (spray-varnish-cost p3) 15) + (= (glaze-cost p3) 20) + (= (grind-cost p3) 45) + (= (plane-cost p3) 30) + (unused p4) + (goalsize p4 medium) + (= (spray-varnish-cost p4) 10) + (= (glaze-cost p4) 15) + (= (grind-cost p4) 30) + (= (plane-cost p4) 20) + (unused p5) + (goalsize p5 large) + (= (spray-varnish-cost p5) 15) + (= (glaze-cost p5) 20) + (= (grind-cost p5) 45) + (= (plane-cost p5) 30) + (unused p6) + (goalsize p6 small) + (= (spray-varnish-cost p6) 5) + (= (glaze-cost p6) 10) + (= (grind-cost p6) 15) + (= (plane-cost p6) 10) + (unused p7) + (goalsize p7 large) + (= (spray-varnish-cost p7) 15) + (= (glaze-cost p7) 20) + (= (grind-cost p7) 45) + (= (plane-cost p7) 30) + (available p8) + (colour p8 black) + (wood p8 walnut) + (surface-condition p8 verysmooth) + (treatment p8 colourfragments) + (goalsize p8 small) + (= (spray-varnish-cost p8) 5) + (= (glaze-cost p8) 10) + (= (grind-cost p8) 15) + (= (plane-cost p8) 10) + (unused p9) + (goalsize p9 medium) + (= (spray-varnish-cost p9) 10) + (= (glaze-cost p9) 15) + (= (grind-cost p9) 30) + (= (plane-cost p9) 20) + (unused p10) + (goalsize p10 small) + (= (spray-varnish-cost p10) 5) + (= (glaze-cost p10) 10) + (= (grind-cost p10) 15) + (= (plane-cost p10) 10) + (unused p11) + (goalsize p11 large) + (= (spray-varnish-cost p11) 15) + (= (glaze-cost p11) 20) + (= (grind-cost p11) 45) + (= (plane-cost p11) 30) + (available p12) + (colour p12 red) + (wood p12 walnut) + (surface-condition p12 verysmooth) + (treatment p12 glazed) + (goalsize p12 small) + (= (spray-varnish-cost p12) 5) + (= (glaze-cost p12) 10) + (= (grind-cost p12) 15) + (= (plane-cost p12) 10) + (unused p13) + (goalsize p13 small) + (= (spray-varnish-cost p13) 5) + (= (glaze-cost p13) 10) + (= (grind-cost p13) 15) + (= (plane-cost p13) 10) + (unused p14) + (goalsize p14 small) + (= (spray-varnish-cost p14) 5) + (= (glaze-cost p14) 10) + (= (grind-cost p14) 15) + (= (plane-cost p14) 10) + (unused p15) + (goalsize p15 large) + (= (spray-varnish-cost p15) 15) + (= (glaze-cost p15) 20) + (= (grind-cost p15) 45) + (= (plane-cost p15) 30) + (unused p16) + (goalsize p16 large) + (= (spray-varnish-cost p16) 15) + (= (glaze-cost p16) 20) + (= (grind-cost p16) 45) + (= (plane-cost p16) 30) + (available p17) + (colour p17 natural) + (wood p17 teak) + (surface-condition p17 verysmooth) + (treatment p17 varnished) + (goalsize p17 large) + (= (spray-varnish-cost p17) 15) + (= (glaze-cost p17) 20) + (= (grind-cost p17) 45) + (= (plane-cost p17) 30) + (boardsize b0 s9) + (wood b0 beech) + (surface-condition b0 smooth) + (available b0) + (boardsize b1 s3) + (wood b1 beech) + (surface-condition b1 rough) + (available b1) + (boardsize b2 s4) + (wood b2 teak) + (surface-condition b2 rough) + (available b2) + (boardsize b3 s9) + (wood b3 oak) + (surface-condition b3 rough) + (available b3) + (boardsize b4 s2) + (wood b4 oak) + (surface-condition b4 rough) + (available b4) + (boardsize b5 s4) + (wood b5 cherry) + (surface-condition b5 rough) + (available b5) + (boardsize b6 s6) + (wood b6 walnut) + (surface-condition b6 rough) + (available b6) + ) + (:goal + (and + (available p0) + (surface-condition p0 verysmooth) + (treatment p0 varnished) + (available p1) + (surface-condition p1 smooth) + (treatment p1 varnished) + (available p2) + (colour p2 green) + (surface-condition p2 smooth) + (treatment p2 glazed) + (available p3) + (colour p3 natural) + (wood p3 walnut) + (surface-condition p3 smooth) + (treatment p3 glazed) + (available p4) + (colour p4 white) + (wood p4 teak) + (available p5) + (colour p5 mauve) + (wood p5 beech) + (available p6) + (colour p6 green) + (wood p6 oak) + (available p7) + (surface-condition p7 verysmooth) + (treatment p7 glazed) + (available p8) + (colour p8 natural) + (treatment p8 varnished) + (available p9) + (wood p9 oak) + (surface-condition p9 verysmooth) + (available p10) + (colour p10 blue) + (surface-condition p10 verysmooth) + (available p11) + (colour p11 blue) + (wood p11 beech) + (available p12) + (colour p12 green) + (wood p12 walnut) + (surface-condition p12 verysmooth) + (treatment p12 glazed) + (available p13) + (colour p13 black) + (surface-condition p13 verysmooth) + (treatment p13 varnished) + (available p14) + (colour p14 blue) + (wood p14 beech) + (available p15) + (colour p15 mauve) + (wood p15 beech) + (available p16) + (surface-condition p16 smooth) + (treatment p16 glazed) + (available p17) + (colour p17 blue) + (wood p17 teak) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p17.pddl b/data/woodworking-sat08-strips/p17.pddl new file mode 100644 index 00000000..01d938aa --- /dev/null +++ b/data/woodworking-sat08-strips/p17.pddl @@ -0,0 +1,324 @@ +; woodworking task with 21 parts and 120% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 654403 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + blue black red white mauve green - acolour + pine beech walnut cherry teak - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 p18 p19 p20 - part + b0 b1 b2 b3 b4 b5 b6 b7 - board + s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (boardsize-successor s7 s8) + (boardsize-successor s8 s9) + (has-colour glazer0 blue) + (has-colour glazer0 natural) + (has-colour glazer0 mauve) + (has-colour glazer0 green) + (has-colour glazer0 black) + (has-colour glazer0 red) + (has-colour immersion-varnisher0 blue) + (has-colour immersion-varnisher0 natural) + (has-colour immersion-varnisher0 mauve) + (has-colour immersion-varnisher0 black) + (has-colour immersion-varnisher0 green) + (has-colour immersion-varnisher0 red) + (empty highspeed-saw0) + (has-colour spray-varnisher0 blue) + (has-colour spray-varnisher0 natural) + (has-colour spray-varnisher0 mauve) + (has-colour spray-varnisher0 black) + (has-colour spray-varnisher0 green) + (has-colour spray-varnisher0 red) + (unused p0) + (goalsize p0 small) + (= (spray-varnish-cost p0) 5) + (= (glaze-cost p0) 10) + (= (grind-cost p0) 15) + (= (plane-cost p0) 10) + (unused p1) + (goalsize p1 small) + (= (spray-varnish-cost p1) 5) + (= (glaze-cost p1) 10) + (= (grind-cost p1) 15) + (= (plane-cost p1) 10) + (unused p2) + (goalsize p2 medium) + (= (spray-varnish-cost p2) 10) + (= (glaze-cost p2) 15) + (= (grind-cost p2) 30) + (= (plane-cost p2) 20) + (unused p3) + (goalsize p3 small) + (= (spray-varnish-cost p3) 5) + (= (glaze-cost p3) 10) + (= (grind-cost p3) 15) + (= (plane-cost p3) 10) + (unused p4) + (goalsize p4 medium) + (= (spray-varnish-cost p4) 10) + (= (glaze-cost p4) 15) + (= (grind-cost p4) 30) + (= (plane-cost p4) 20) + (available p5) + (colour p5 mauve) + (wood p5 teak) + (surface-condition p5 rough) + (treatment p5 glazed) + (goalsize p5 small) + (= (spray-varnish-cost p5) 5) + (= (glaze-cost p5) 10) + (= (grind-cost p5) 15) + (= (plane-cost p5) 10) + (unused p6) + (goalsize p6 large) + (= (spray-varnish-cost p6) 15) + (= (glaze-cost p6) 20) + (= (grind-cost p6) 45) + (= (plane-cost p6) 30) + (unused p7) + (goalsize p7 large) + (= (spray-varnish-cost p7) 15) + (= (glaze-cost p7) 20) + (= (grind-cost p7) 45) + (= (plane-cost p7) 30) + (unused p8) + (goalsize p8 large) + (= (spray-varnish-cost p8) 15) + (= (glaze-cost p8) 20) + (= (grind-cost p8) 45) + (= (plane-cost p8) 30) + (unused p9) + (goalsize p9 medium) + (= (spray-varnish-cost p9) 10) + (= (glaze-cost p9) 15) + (= (grind-cost p9) 30) + (= (plane-cost p9) 20) + (unused p10) + (goalsize p10 large) + (= (spray-varnish-cost p10) 15) + (= (glaze-cost p10) 20) + (= (grind-cost p10) 45) + (= (plane-cost p10) 30) + (available p11) + (colour p11 white) + (wood p11 walnut) + (surface-condition p11 rough) + (treatment p11 colourfragments) + (goalsize p11 small) + (= (spray-varnish-cost p11) 5) + (= (glaze-cost p11) 10) + (= (grind-cost p11) 15) + (= (plane-cost p11) 10) + (available p12) + (colour p12 black) + (wood p12 teak) + (surface-condition p12 rough) + (treatment p12 glazed) + (goalsize p12 small) + (= (spray-varnish-cost p12) 5) + (= (glaze-cost p12) 10) + (= (grind-cost p12) 15) + (= (plane-cost p12) 10) + (available p13) + (colour p13 green) + (wood p13 beech) + (surface-condition p13 smooth) + (treatment p13 varnished) + (goalsize p13 medium) + (= (spray-varnish-cost p13) 10) + (= (glaze-cost p13) 15) + (= (grind-cost p13) 30) + (= (plane-cost p13) 20) + (unused p14) + (goalsize p14 large) + (= (spray-varnish-cost p14) 15) + (= (glaze-cost p14) 20) + (= (grind-cost p14) 45) + (= (plane-cost p14) 30) + (unused p15) + (goalsize p15 large) + (= (spray-varnish-cost p15) 15) + (= (glaze-cost p15) 20) + (= (grind-cost p15) 45) + (= (plane-cost p15) 30) + (unused p16) + (goalsize p16 medium) + (= (spray-varnish-cost p16) 10) + (= (glaze-cost p16) 15) + (= (grind-cost p16) 30) + (= (plane-cost p16) 20) + (unused p17) + (goalsize p17 small) + (= (spray-varnish-cost p17) 5) + (= (glaze-cost p17) 10) + (= (grind-cost p17) 15) + (= (plane-cost p17) 10) + (unused p18) + (goalsize p18 medium) + (= (spray-varnish-cost p18) 10) + (= (glaze-cost p18) 15) + (= (grind-cost p18) 30) + (= (plane-cost p18) 20) + (unused p19) + (goalsize p19 small) + (= (spray-varnish-cost p19) 5) + (= (glaze-cost p19) 10) + (= (grind-cost p19) 15) + (= (plane-cost p19) 10) + (available p20) + (colour p20 white) + (wood p20 beech) + (surface-condition p20 smooth) + (treatment p20 colourfragments) + (goalsize p20 medium) + (= (spray-varnish-cost p20) 10) + (= (glaze-cost p20) 15) + (= (grind-cost p20) 30) + (= (plane-cost p20) 20) + (boardsize b0 s8) + (wood b0 beech) + (surface-condition b0 rough) + (available b0) + (boardsize b1 s3) + (wood b1 beech) + (surface-condition b1 rough) + (available b1) + (boardsize b2 s5) + (wood b2 teak) + (surface-condition b2 rough) + (available b2) + (boardsize b3 s5) + (wood b3 cherry) + (surface-condition b3 rough) + (available b3) + (boardsize b4 s7) + (wood b4 pine) + (surface-condition b4 rough) + (available b4) + (boardsize b5 s1) + (wood b5 pine) + (surface-condition b5 rough) + (available b5) + (boardsize b6 s9) + (wood b6 walnut) + (surface-condition b6 rough) + (available b6) + (boardsize b7 s3) + (wood b7 walnut) + (surface-condition b7 rough) + (available b7) + ) + (:goal + (and + (available p0) + (colour p0 green) + (wood p0 pine) + (available p1) + (colour p1 natural) + (treatment p1 glazed) + (available p2) + (colour p2 natural) + (surface-condition p2 smooth) + (available p3) + (colour p3 natural) + (treatment p3 glazed) + (available p4) + (colour p4 mauve) + (wood p4 teak) + (surface-condition p4 verysmooth) + (available p5) + (colour p5 black) + (wood p5 teak) + (surface-condition p5 smooth) + (treatment p5 varnished) + (available p6) + (colour p6 natural) + (treatment p6 varnished) + (available p7) + (colour p7 red) + (wood p7 cherry) + (surface-condition p7 smooth) + (treatment p7 glazed) + (available p8) + (colour p8 green) + (wood p8 beech) + (surface-condition p8 verysmooth) + (treatment p8 varnished) + (available p9) + (colour p9 red) + (wood p9 pine) + (surface-condition p9 smooth) + (treatment p9 glazed) + (available p10) + (colour p10 mauve) + (surface-condition p10 smooth) + (treatment p10 varnished) + (available p11) + (colour p11 mauve) + (wood p11 walnut) + (surface-condition p11 smooth) + (treatment p11 varnished) + (available p12) + (colour p12 red) + (wood p12 teak) + (available p13) + (colour p13 red) + (surface-condition p13 verysmooth) + (treatment p13 varnished) + (available p14) + (colour p14 black) + (wood p14 beech) + (available p15) + (colour p15 mauve) + (wood p15 walnut) + (available p16) + (wood p16 beech) + (treatment p16 glazed) + (available p17) + (colour p17 mauve) + (treatment p17 varnished) + (available p18) + (colour p18 red) + (treatment p18 glazed) + (available p19) + (colour p19 blue) + (surface-condition p19 verysmooth) + (available p20) + (surface-condition p20 verysmooth) + (treatment p20 glazed) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p18.pddl b/data/woodworking-sat08-strips/p18.pddl new file mode 100644 index 00000000..33426b45 --- /dev/null +++ b/data/woodworking-sat08-strips/p18.pddl @@ -0,0 +1,354 @@ +; woodworking task with 24 parts and 120% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 90334 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + red blue green white mauve black - acolour + cherry pine mahogany teak walnut beech - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 p18 p19 p20 p21 p22 p23 - part + b0 b1 b2 b3 b4 b5 b6 b7 - board + s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (boardsize-successor s7 s8) + (boardsize-successor s8 s9) + (boardsize-successor s9 s10) + (has-colour glazer0 blue) + (has-colour glazer0 black) + (has-colour glazer0 natural) + (has-colour glazer0 green) + (has-colour glazer0 red) + (has-colour immersion-varnisher0 blue) + (has-colour immersion-varnisher0 natural) + (has-colour immersion-varnisher0 mauve) + (has-colour immersion-varnisher0 green) + (has-colour immersion-varnisher0 white) + (has-colour immersion-varnisher0 red) + (empty highspeed-saw0) + (has-colour spray-varnisher0 blue) + (has-colour spray-varnisher0 natural) + (has-colour spray-varnisher0 mauve) + (has-colour spray-varnisher0 green) + (has-colour spray-varnisher0 white) + (has-colour spray-varnisher0 red) + (available p0) + (colour p0 green) + (wood p0 walnut) + (surface-condition p0 rough) + (treatment p0 glazed) + (goalsize p0 small) + (= (spray-varnish-cost p0) 5) + (= (glaze-cost p0) 10) + (= (grind-cost p0) 15) + (= (plane-cost p0) 10) + (unused p1) + (goalsize p1 medium) + (= (spray-varnish-cost p1) 10) + (= (glaze-cost p1) 15) + (= (grind-cost p1) 30) + (= (plane-cost p1) 20) + (unused p2) + (goalsize p2 small) + (= (spray-varnish-cost p2) 5) + (= (glaze-cost p2) 10) + (= (grind-cost p2) 15) + (= (plane-cost p2) 10) + (unused p3) + (goalsize p3 large) + (= (spray-varnish-cost p3) 15) + (= (glaze-cost p3) 20) + (= (grind-cost p3) 45) + (= (plane-cost p3) 30) + (unused p4) + (goalsize p4 small) + (= (spray-varnish-cost p4) 5) + (= (glaze-cost p4) 10) + (= (grind-cost p4) 15) + (= (plane-cost p4) 10) + (available p5) + (colour p5 green) + (wood p5 teak) + (surface-condition p5 rough) + (treatment p5 colourfragments) + (goalsize p5 large) + (= (spray-varnish-cost p5) 15) + (= (glaze-cost p5) 20) + (= (grind-cost p5) 45) + (= (plane-cost p5) 30) + (unused p6) + (goalsize p6 medium) + (= (spray-varnish-cost p6) 10) + (= (glaze-cost p6) 15) + (= (grind-cost p6) 30) + (= (plane-cost p6) 20) + (available p7) + (colour p7 green) + (wood p7 cherry) + (surface-condition p7 rough) + (treatment p7 glazed) + (goalsize p7 large) + (= (spray-varnish-cost p7) 15) + (= (glaze-cost p7) 20) + (= (grind-cost p7) 45) + (= (plane-cost p7) 30) + (unused p8) + (goalsize p8 large) + (= (spray-varnish-cost p8) 15) + (= (glaze-cost p8) 20) + (= (grind-cost p8) 45) + (= (plane-cost p8) 30) + (unused p9) + (goalsize p9 small) + (= (spray-varnish-cost p9) 5) + (= (glaze-cost p9) 10) + (= (grind-cost p9) 15) + (= (plane-cost p9) 10) + (unused p10) + (goalsize p10 large) + (= (spray-varnish-cost p10) 15) + (= (glaze-cost p10) 20) + (= (grind-cost p10) 45) + (= (plane-cost p10) 30) + (available p11) + (colour p11 black) + (wood p11 beech) + (surface-condition p11 rough) + (treatment p11 glazed) + (goalsize p11 medium) + (= (spray-varnish-cost p11) 10) + (= (glaze-cost p11) 15) + (= (grind-cost p11) 30) + (= (plane-cost p11) 20) + (unused p12) + (goalsize p12 medium) + (= (spray-varnish-cost p12) 10) + (= (glaze-cost p12) 15) + (= (grind-cost p12) 30) + (= (plane-cost p12) 20) + (unused p13) + (goalsize p13 medium) + (= (spray-varnish-cost p13) 10) + (= (glaze-cost p13) 15) + (= (grind-cost p13) 30) + (= (plane-cost p13) 20) + (unused p14) + (goalsize p14 medium) + (= (spray-varnish-cost p14) 10) + (= (glaze-cost p14) 15) + (= (grind-cost p14) 30) + (= (plane-cost p14) 20) + (unused p15) + (goalsize p15 small) + (= (spray-varnish-cost p15) 5) + (= (glaze-cost p15) 10) + (= (grind-cost p15) 15) + (= (plane-cost p15) 10) + (unused p16) + (goalsize p16 small) + (= (spray-varnish-cost p16) 5) + (= (glaze-cost p16) 10) + (= (grind-cost p16) 15) + (= (plane-cost p16) 10) + (unused p17) + (goalsize p17 large) + (= (spray-varnish-cost p17) 15) + (= (glaze-cost p17) 20) + (= (grind-cost p17) 45) + (= (plane-cost p17) 30) + (unused p18) + (goalsize p18 small) + (= (spray-varnish-cost p18) 5) + (= (glaze-cost p18) 10) + (= (grind-cost p18) 15) + (= (plane-cost p18) 10) + (unused p19) + (goalsize p19 medium) + (= (spray-varnish-cost p19) 10) + (= (glaze-cost p19) 15) + (= (grind-cost p19) 30) + (= (plane-cost p19) 20) + (available p20) + (colour p20 blue) + (wood p20 mahogany) + (surface-condition p20 smooth) + (treatment p20 varnished) + (goalsize p20 large) + (= (spray-varnish-cost p20) 15) + (= (glaze-cost p20) 20) + (= (grind-cost p20) 45) + (= (plane-cost p20) 30) + (unused p21) + (goalsize p21 medium) + (= (spray-varnish-cost p21) 10) + (= (glaze-cost p21) 15) + (= (grind-cost p21) 30) + (= (plane-cost p21) 20) + (unused p22) + (goalsize p22 medium) + (= (spray-varnish-cost p22) 10) + (= (glaze-cost p22) 15) + (= (grind-cost p22) 30) + (= (plane-cost p22) 20) + (unused p23) + (goalsize p23 large) + (= (spray-varnish-cost p23) 15) + (= (glaze-cost p23) 20) + (= (grind-cost p23) 45) + (= (plane-cost p23) 30) + (boardsize b0 s6) + (wood b0 cherry) + (surface-condition b0 smooth) + (available b0) + (boardsize b1 s5) + (wood b1 mahogany) + (surface-condition b1 rough) + (available b1) + (boardsize b2 s4) + (wood b2 pine) + (surface-condition b2 smooth) + (available b2) + (boardsize b3 s10) + (wood b3 walnut) + (surface-condition b3 rough) + (available b3) + (boardsize b4 s2) + (wood b4 walnut) + (surface-condition b4 rough) + (available b4) + (boardsize b5 s9) + (wood b5 teak) + (surface-condition b5 rough) + (available b5) + (boardsize b6 s6) + (wood b6 teak) + (surface-condition b6 rough) + (available b6) + (boardsize b7 s4) + (wood b7 beech) + (surface-condition b7 smooth) + (available b7) + ) + (:goal + (and + (available p0) + (colour p0 red) + (wood p0 walnut) + (surface-condition p0 smooth) + (treatment p0 varnished) + (available p1) + (wood p1 walnut) + (surface-condition p1 verysmooth) + (available p2) + (colour p2 green) + (wood p2 teak) + (available p3) + (colour p3 blue) + (wood p3 teak) + (available p4) + (wood p4 mahogany) + (surface-condition p4 verysmooth) + (available p5) + (wood p5 teak) + (surface-condition p5 verysmooth) + (available p6) + (wood p6 pine) + (surface-condition p6 verysmooth) + (available p7) + (wood p7 cherry) + (treatment p7 varnished) + (available p8) + (colour p8 white) + (wood p8 walnut) + (surface-condition p8 smooth) + (treatment p8 varnished) + (available p9) + (colour p9 mauve) + (wood p9 pine) + (surface-condition p9 smooth) + (treatment p9 varnished) + (available p10) + (colour p10 mauve) + (treatment p10 varnished) + (available p11) + (colour p11 red) + (treatment p11 glazed) + (available p12) + (colour p12 natural) + (wood p12 teak) + (surface-condition p12 verysmooth) + (treatment p12 varnished) + (available p13) + (colour p13 red) + (surface-condition p13 smooth) + (available p14) + (colour p14 black) + (wood p14 teak) + (surface-condition p14 verysmooth) + (treatment p14 glazed) + (available p15) + (colour p15 natural) + (surface-condition p15 verysmooth) + (treatment p15 glazed) + (available p16) + (colour p16 black) + (wood p16 cherry) + (surface-condition p16 smooth) + (treatment p16 glazed) + (available p17) + (colour p17 green) + (treatment p17 varnished) + (available p18) + (colour p18 natural) + (wood p18 mahogany) + (treatment p18 glazed) + (available p19) + (colour p19 mauve) + (wood p19 walnut) + (surface-condition p19 smooth) + (treatment p19 varnished) + (available p20) + (colour p20 natural) + (treatment p20 varnished) + (available p21) + (wood p21 mahogany) + (surface-condition p21 smooth) + (available p22) + (wood p22 teak) + (treatment p22 varnished) + (available p23) + (wood p23 cherry) + (treatment p23 varnished) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p19.pddl b/data/woodworking-sat08-strips/p19.pddl new file mode 100644 index 00000000..6502a587 --- /dev/null +++ b/data/woodworking-sat08-strips/p19.pddl @@ -0,0 +1,400 @@ +; woodworking task with 27 parts and 120% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 331662 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + black green white red mauve blue - acolour + oak mahogany walnut cherry teak pine beech - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 p18 p19 p20 p21 p22 p23 p24 p25 p26 - part + b0 b1 b2 b3 b4 b5 b6 b7 b8 - board + s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (boardsize-successor s7 s8) + (boardsize-successor s8 s9) + (has-colour glazer0 blue) + (has-colour glazer0 natural) + (has-colour glazer0 white) + (has-colour glazer0 black) + (has-colour immersion-varnisher0 blue) + (has-colour immersion-varnisher0 natural) + (has-colour immersion-varnisher0 mauve) + (has-colour immersion-varnisher0 green) + (has-colour immersion-varnisher0 black) + (has-colour immersion-varnisher0 white) + (has-colour immersion-varnisher0 red) + (empty highspeed-saw0) + (has-colour spray-varnisher0 blue) + (has-colour spray-varnisher0 natural) + (has-colour spray-varnisher0 mauve) + (has-colour spray-varnisher0 green) + (has-colour spray-varnisher0 black) + (has-colour spray-varnisher0 white) + (has-colour spray-varnisher0 red) + (available p0) + (colour p0 mauve) + (wood p0 pine) + (surface-condition p0 smooth) + (treatment p0 glazed) + (goalsize p0 large) + (= (spray-varnish-cost p0) 15) + (= (glaze-cost p0) 20) + (= (grind-cost p0) 45) + (= (plane-cost p0) 30) + (unused p1) + (goalsize p1 large) + (= (spray-varnish-cost p1) 15) + (= (glaze-cost p1) 20) + (= (grind-cost p1) 45) + (= (plane-cost p1) 30) + (available p2) + (colour p2 red) + (wood p2 teak) + (surface-condition p2 smooth) + (treatment p2 glazed) + (goalsize p2 large) + (= (spray-varnish-cost p2) 15) + (= (glaze-cost p2) 20) + (= (grind-cost p2) 45) + (= (plane-cost p2) 30) + (available p3) + (colour p3 natural) + (wood p3 cherry) + (surface-condition p3 verysmooth) + (treatment p3 glazed) + (goalsize p3 small) + (= (spray-varnish-cost p3) 5) + (= (glaze-cost p3) 10) + (= (grind-cost p3) 15) + (= (plane-cost p3) 10) + (unused p4) + (goalsize p4 large) + (= (spray-varnish-cost p4) 15) + (= (glaze-cost p4) 20) + (= (grind-cost p4) 45) + (= (plane-cost p4) 30) + (unused p5) + (goalsize p5 large) + (= (spray-varnish-cost p5) 15) + (= (glaze-cost p5) 20) + (= (grind-cost p5) 45) + (= (plane-cost p5) 30) + (unused p6) + (goalsize p6 small) + (= (spray-varnish-cost p6) 5) + (= (glaze-cost p6) 10) + (= (grind-cost p6) 15) + (= (plane-cost p6) 10) + (unused p7) + (goalsize p7 small) + (= (spray-varnish-cost p7) 5) + (= (glaze-cost p7) 10) + (= (grind-cost p7) 15) + (= (plane-cost p7) 10) + (unused p8) + (goalsize p8 large) + (= (spray-varnish-cost p8) 15) + (= (glaze-cost p8) 20) + (= (grind-cost p8) 45) + (= (plane-cost p8) 30) + (unused p9) + (goalsize p9 medium) + (= (spray-varnish-cost p9) 10) + (= (glaze-cost p9) 15) + (= (grind-cost p9) 30) + (= (plane-cost p9) 20) + (unused p10) + (goalsize p10 small) + (= (spray-varnish-cost p10) 5) + (= (glaze-cost p10) 10) + (= (grind-cost p10) 15) + (= (plane-cost p10) 10) + (unused p11) + (goalsize p11 small) + (= (spray-varnish-cost p11) 5) + (= (glaze-cost p11) 10) + (= (grind-cost p11) 15) + (= (plane-cost p11) 10) + (unused p12) + (goalsize p12 large) + (= (spray-varnish-cost p12) 15) + (= (glaze-cost p12) 20) + (= (grind-cost p12) 45) + (= (plane-cost p12) 30) + (unused p13) + (goalsize p13 small) + (= (spray-varnish-cost p13) 5) + (= (glaze-cost p13) 10) + (= (grind-cost p13) 15) + (= (plane-cost p13) 10) + (unused p14) + (goalsize p14 small) + (= (spray-varnish-cost p14) 5) + (= (glaze-cost p14) 10) + (= (grind-cost p14) 15) + (= (plane-cost p14) 10) + (available p15) + (colour p15 red) + (wood p15 beech) + (surface-condition p15 verysmooth) + (treatment p15 varnished) + (goalsize p15 medium) + (= (spray-varnish-cost p15) 10) + (= (glaze-cost p15) 15) + (= (grind-cost p15) 30) + (= (plane-cost p15) 20) + (unused p16) + (goalsize p16 large) + (= (spray-varnish-cost p16) 15) + (= (glaze-cost p16) 20) + (= (grind-cost p16) 45) + (= (plane-cost p16) 30) + (unused p17) + (goalsize p17 medium) + (= (spray-varnish-cost p17) 10) + (= (glaze-cost p17) 15) + (= (grind-cost p17) 30) + (= (plane-cost p17) 20) + (unused p18) + (goalsize p18 medium) + (= (spray-varnish-cost p18) 10) + (= (glaze-cost p18) 15) + (= (grind-cost p18) 30) + (= (plane-cost p18) 20) + (available p19) + (colour p19 mauve) + (wood p19 cherry) + (surface-condition p19 smooth) + (treatment p19 colourfragments) + (goalsize p19 medium) + (= (spray-varnish-cost p19) 10) + (= (glaze-cost p19) 15) + (= (grind-cost p19) 30) + (= (plane-cost p19) 20) + (unused p20) + (goalsize p20 medium) + (= (spray-varnish-cost p20) 10) + (= (glaze-cost p20) 15) + (= (grind-cost p20) 30) + (= (plane-cost p20) 20) + (unused p21) + (goalsize p21 large) + (= (spray-varnish-cost p21) 15) + (= (glaze-cost p21) 20) + (= (grind-cost p21) 45) + (= (plane-cost p21) 30) + (available p22) + (colour p22 blue) + (wood p22 teak) + (surface-condition p22 rough) + (treatment p22 colourfragments) + (goalsize p22 small) + (= (spray-varnish-cost p22) 5) + (= (glaze-cost p22) 10) + (= (grind-cost p22) 15) + (= (plane-cost p22) 10) + (unused p23) + (goalsize p23 medium) + (= (spray-varnish-cost p23) 10) + (= (glaze-cost p23) 15) + (= (grind-cost p23) 30) + (= (plane-cost p23) 20) + (available p24) + (colour p24 natural) + (wood p24 pine) + (surface-condition p24 verysmooth) + (treatment p24 colourfragments) + (goalsize p24 small) + (= (spray-varnish-cost p24) 5) + (= (glaze-cost p24) 10) + (= (grind-cost p24) 15) + (= (plane-cost p24) 10) + (unused p25) + (goalsize p25 large) + (= (spray-varnish-cost p25) 15) + (= (glaze-cost p25) 20) + (= (grind-cost p25) 45) + (= (plane-cost p25) 30) + (available p26) + (colour p26 mauve) + (wood p26 oak) + (surface-condition p26 verysmooth) + (treatment p26 colourfragments) + (goalsize p26 small) + (= (spray-varnish-cost p26) 5) + (= (glaze-cost p26) 10) + (= (grind-cost p26) 15) + (= (plane-cost p26) 10) + (boardsize b0 s5) + (wood b0 cherry) + (surface-condition b0 smooth) + (available b0) + (boardsize b1 s8) + (wood b1 mahogany) + (surface-condition b1 rough) + (available b1) + (boardsize b2 s5) + (wood b2 oak) + (surface-condition b2 rough) + (available b2) + (boardsize b3 s8) + (wood b3 pine) + (surface-condition b3 rough) + (available b3) + (boardsize b4 s9) + (wood b4 walnut) + (surface-condition b4 rough) + (available b4) + (boardsize b5 s3) + (wood b5 walnut) + (surface-condition b5 rough) + (available b5) + (boardsize b6 s2) + (wood b6 teak) + (surface-condition b6 rough) + (available b6) + (boardsize b7 s8) + (wood b7 beech) + (surface-condition b7 rough) + (available b7) + (boardsize b8 s3) + (wood b8 beech) + (surface-condition b8 rough) + (available b8) + ) + (:goal + (and + (available p0) + (colour p0 black) + (wood p0 pine) + (surface-condition p0 smooth) + (treatment p0 varnished) + (available p1) + (wood p1 beech) + (treatment p1 varnished) + (available p2) + (surface-condition p2 smooth) + (treatment p2 varnished) + (available p3) + (colour p3 white) + (surface-condition p3 smooth) + (available p4) + (colour p4 mauve) + (wood p4 walnut) + (surface-condition p4 smooth) + (treatment p4 varnished) + (available p5) + (colour p5 natural) + (wood p5 walnut) + (surface-condition p5 smooth) + (treatment p5 glazed) + (available p6) + (colour p6 natural) + (wood p6 teak) + (available p7) + (wood p7 cherry) + (treatment p7 varnished) + (available p8) + (colour p8 blue) + (wood p8 pine) + (available p9) + (surface-condition p9 verysmooth) + (treatment p9 varnished) + (available p10) + (colour p10 blue) + (wood p10 pine) + (treatment p10 varnished) + (available p11) + (colour p11 mauve) + (surface-condition p11 verysmooth) + (treatment p11 varnished) + (available p12) + (wood p12 cherry) + (treatment p12 glazed) + (available p13) + (colour p13 white) + (treatment p13 glazed) + (available p14) + (wood p14 beech) + (surface-condition p14 verysmooth) + (available p15) + (wood p15 beech) + (surface-condition p15 smooth) + (available p16) + (wood p16 mahogany) + (treatment p16 varnished) + (available p17) + (colour p17 natural) + (treatment p17 glazed) + (available p18) + (colour p18 green) + (wood p18 pine) + (surface-condition p18 smooth) + (treatment p18 varnished) + (available p19) + (colour p19 natural) + (wood p19 cherry) + (surface-condition p19 verysmooth) + (treatment p19 varnished) + (available p20) + (colour p20 blue) + (wood p20 oak) + (available p21) + (colour p21 black) + (wood p21 beech) + (surface-condition p21 verysmooth) + (treatment p21 glazed) + (available p22) + (wood p22 teak) + (treatment p22 varnished) + (available p23) + (wood p23 walnut) + (surface-condition p23 smooth) + (treatment p23 glazed) + (available p24) + (colour p24 blue) + (wood p24 pine) + (surface-condition p24 smooth) + (treatment p24 varnished) + (available p25) + (colour p25 blue) + (wood p25 mahogany) + (available p26) + (colour p26 red) + (wood p26 oak) + (surface-condition p26 smooth) + (treatment p26 varnished) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p20.pddl b/data/woodworking-sat08-strips/p20.pddl new file mode 100644 index 00000000..8d46365e --- /dev/null +++ b/data/woodworking-sat08-strips/p20.pddl @@ -0,0 +1,421 @@ +; woodworking task with 30 parts and 120% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 702790 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + red green blue white black mauve - acolour + mahogany teak walnut beech oak cherry pine - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 p18 p19 p20 p21 p22 p23 p24 p25 p26 p27 p28 p29 - part + b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 - board + s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (boardsize-successor s7 s8) + (boardsize-successor s8 s9) + (boardsize-successor s9 s10) + (boardsize-successor s10 s11) + (has-colour glazer0 blue) + (has-colour glazer0 natural) + (has-colour glazer0 mauve) + (has-colour glazer0 green) + (has-colour glazer0 black) + (has-colour glazer0 white) + (has-colour glazer0 red) + (has-colour immersion-varnisher0 blue) + (has-colour immersion-varnisher0 natural) + (has-colour immersion-varnisher0 mauve) + (has-colour immersion-varnisher0 black) + (has-colour immersion-varnisher0 green) + (has-colour immersion-varnisher0 white) + (has-colour immersion-varnisher0 red) + (empty highspeed-saw0) + (has-colour spray-varnisher0 blue) + (has-colour spray-varnisher0 natural) + (has-colour spray-varnisher0 mauve) + (has-colour spray-varnisher0 black) + (has-colour spray-varnisher0 green) + (has-colour spray-varnisher0 white) + (has-colour spray-varnisher0 red) + (unused p0) + (goalsize p0 medium) + (= (spray-varnish-cost p0) 10) + (= (glaze-cost p0) 15) + (= (grind-cost p0) 30) + (= (plane-cost p0) 20) + (unused p1) + (goalsize p1 small) + (= (spray-varnish-cost p1) 5) + (= (glaze-cost p1) 10) + (= (grind-cost p1) 15) + (= (plane-cost p1) 10) + (unused p2) + (goalsize p2 small) + (= (spray-varnish-cost p2) 5) + (= (glaze-cost p2) 10) + (= (grind-cost p2) 15) + (= (plane-cost p2) 10) + (available p3) + (colour p3 blue) + (wood p3 pine) + (surface-condition p3 smooth) + (treatment p3 glazed) + (goalsize p3 small) + (= (spray-varnish-cost p3) 5) + (= (glaze-cost p3) 10) + (= (grind-cost p3) 15) + (= (plane-cost p3) 10) + (unused p4) + (goalsize p4 large) + (= (spray-varnish-cost p4) 15) + (= (glaze-cost p4) 20) + (= (grind-cost p4) 45) + (= (plane-cost p4) 30) + (unused p5) + (goalsize p5 medium) + (= (spray-varnish-cost p5) 10) + (= (glaze-cost p5) 15) + (= (grind-cost p5) 30) + (= (plane-cost p5) 20) + (unused p6) + (goalsize p6 medium) + (= (spray-varnish-cost p6) 10) + (= (glaze-cost p6) 15) + (= (grind-cost p6) 30) + (= (plane-cost p6) 20) + (unused p7) + (goalsize p7 small) + (= (spray-varnish-cost p7) 5) + (= (glaze-cost p7) 10) + (= (grind-cost p7) 15) + (= (plane-cost p7) 10) + (unused p8) + (goalsize p8 medium) + (= (spray-varnish-cost p8) 10) + (= (glaze-cost p8) 15) + (= (grind-cost p8) 30) + (= (plane-cost p8) 20) + (unused p9) + (goalsize p9 small) + (= (spray-varnish-cost p9) 5) + (= (glaze-cost p9) 10) + (= (grind-cost p9) 15) + (= (plane-cost p9) 10) + (unused p10) + (goalsize p10 medium) + (= (spray-varnish-cost p10) 10) + (= (glaze-cost p10) 15) + (= (grind-cost p10) 30) + (= (plane-cost p10) 20) + (unused p11) + (goalsize p11 large) + (= (spray-varnish-cost p11) 15) + (= (glaze-cost p11) 20) + (= (grind-cost p11) 45) + (= (plane-cost p11) 30) + (unused p12) + (goalsize p12 medium) + (= (spray-varnish-cost p12) 10) + (= (glaze-cost p12) 15) + (= (grind-cost p12) 30) + (= (plane-cost p12) 20) + (unused p13) + (goalsize p13 small) + (= (spray-varnish-cost p13) 5) + (= (glaze-cost p13) 10) + (= (grind-cost p13) 15) + (= (plane-cost p13) 10) + (unused p14) + (goalsize p14 medium) + (= (spray-varnish-cost p14) 10) + (= (glaze-cost p14) 15) + (= (grind-cost p14) 30) + (= (plane-cost p14) 20) + (unused p15) + (goalsize p15 small) + (= (spray-varnish-cost p15) 5) + (= (glaze-cost p15) 10) + (= (grind-cost p15) 15) + (= (plane-cost p15) 10) + (unused p16) + (goalsize p16 large) + (= (spray-varnish-cost p16) 15) + (= (glaze-cost p16) 20) + (= (grind-cost p16) 45) + (= (plane-cost p16) 30) + (unused p17) + (goalsize p17 large) + (= (spray-varnish-cost p17) 15) + (= (glaze-cost p17) 20) + (= (grind-cost p17) 45) + (= (plane-cost p17) 30) + (unused p18) + (goalsize p18 large) + (= (spray-varnish-cost p18) 15) + (= (glaze-cost p18) 20) + (= (grind-cost p18) 45) + (= (plane-cost p18) 30) + (available p19) + (colour p19 white) + (wood p19 mahogany) + (surface-condition p19 rough) + (treatment p19 colourfragments) + (goalsize p19 medium) + (= (spray-varnish-cost p19) 10) + (= (glaze-cost p19) 15) + (= (grind-cost p19) 30) + (= (plane-cost p19) 20) + (unused p20) + (goalsize p20 large) + (= (spray-varnish-cost p20) 15) + (= (glaze-cost p20) 20) + (= (grind-cost p20) 45) + (= (plane-cost p20) 30) + (unused p21) + (goalsize p21 large) + (= (spray-varnish-cost p21) 15) + (= (glaze-cost p21) 20) + (= (grind-cost p21) 45) + (= (plane-cost p21) 30) + (unused p22) + (goalsize p22 large) + (= (spray-varnish-cost p22) 15) + (= (glaze-cost p22) 20) + (= (grind-cost p22) 45) + (= (plane-cost p22) 30) + (unused p23) + (goalsize p23 small) + (= (spray-varnish-cost p23) 5) + (= (glaze-cost p23) 10) + (= (grind-cost p23) 15) + (= (plane-cost p23) 10) + (available p24) + (colour p24 black) + (wood p24 teak) + (surface-condition p24 verysmooth) + (treatment p24 glazed) + (goalsize p24 large) + (= (spray-varnish-cost p24) 15) + (= (glaze-cost p24) 20) + (= (grind-cost p24) 45) + (= (plane-cost p24) 30) + (unused p25) + (goalsize p25 small) + (= (spray-varnish-cost p25) 5) + (= (glaze-cost p25) 10) + (= (grind-cost p25) 15) + (= (plane-cost p25) 10) + (unused p26) + (goalsize p26 small) + (= (spray-varnish-cost p26) 5) + (= (glaze-cost p26) 10) + (= (grind-cost p26) 15) + (= (plane-cost p26) 10) + (unused p27) + (goalsize p27 small) + (= (spray-varnish-cost p27) 5) + (= (glaze-cost p27) 10) + (= (grind-cost p27) 15) + (= (plane-cost p27) 10) + (unused p28) + (goalsize p28 medium) + (= (spray-varnish-cost p28) 10) + (= (glaze-cost p28) 15) + (= (grind-cost p28) 30) + (= (plane-cost p28) 20) + (unused p29) + (goalsize p29 large) + (= (spray-varnish-cost p29) 15) + (= (glaze-cost p29) 20) + (= (grind-cost p29) 45) + (= (plane-cost p29) 30) + (boardsize b0 s9) + (wood b0 cherry) + (surface-condition b0 rough) + (available b0) + (boardsize b1 s2) + (wood b1 cherry) + (surface-condition b1 rough) + (available b1) + (boardsize b2 s9) + (wood b2 mahogany) + (surface-condition b2 rough) + (available b2) + (boardsize b3 s5) + (wood b3 mahogany) + (surface-condition b3 smooth) + (available b3) + (boardsize b4 s9) + (wood b4 oak) + (surface-condition b4 rough) + (available b4) + (boardsize b5 s6) + (wood b5 pine) + (surface-condition b5 rough) + (available b5) + (boardsize b6 s5) + (wood b6 walnut) + (surface-condition b6 rough) + (available b6) + (boardsize b7 s11) + (wood b7 teak) + (surface-condition b7 rough) + (available b7) + (boardsize b8 s4) + (wood b8 teak) + (surface-condition b8 rough) + (available b8) + (boardsize b9 s5) + (wood b9 beech) + (surface-condition b9 rough) + (available b9) + (boardsize b10 s1) + (wood b10 beech) + (surface-condition b10 smooth) + (available b10) + ) + (:goal + (and + (available p0) + (colour p0 blue) + (wood p0 beech) + (surface-condition p0 smooth) + (available p1) + (colour p1 mauve) + (wood p1 walnut) + (surface-condition p1 verysmooth) + (available p2) + (wood p2 mahogany) + (surface-condition p2 smooth) + (available p3) + (colour p3 black) + (surface-condition p3 verysmooth) + (available p4) + (colour p4 black) + (wood p4 walnut) + (surface-condition p4 smooth) + (treatment p4 varnished) + (available p5) + (surface-condition p5 verysmooth) + (treatment p5 glazed) + (available p6) + (colour p6 mauve) + (wood p6 cherry) + (surface-condition p6 verysmooth) + (available p7) + (colour p7 black) + (wood p7 beech) + (surface-condition p7 smooth) + (treatment p7 varnished) + (available p8) + (colour p8 natural) + (surface-condition p8 smooth) + (available p9) + (colour p9 green) + (wood p9 pine) + (surface-condition p9 verysmooth) + (available p10) + (colour p10 mauve) + (treatment p10 glazed) + (available p11) + (colour p11 green) + (wood p11 pine) + (surface-condition p11 verysmooth) + (available p12) + (colour p12 red) + (wood p12 teak) + (available p13) + (colour p13 green) + (wood p13 mahogany) + (surface-condition p13 smooth) + (treatment p13 glazed) + (available p14) + (colour p14 white) + (surface-condition p14 verysmooth) + (available p15) + (wood p15 beech) + (treatment p15 varnished) + (available p16) + (colour p16 white) + (wood p16 cherry) + (surface-condition p16 smooth) + (treatment p16 glazed) + (available p17) + (wood p17 teak) + (treatment p17 varnished) + (available p18) + (colour p18 natural) + (surface-condition p18 verysmooth) + (available p19) + (colour p19 black) + (treatment p19 glazed) + (available p20) + (surface-condition p20 smooth) + (treatment p20 glazed) + (available p21) + (wood p21 oak) + (surface-condition p21 smooth) + (available p22) + (colour p22 black) + (wood p22 teak) + (surface-condition p22 smooth) + (available p23) + (colour p23 natural) + (wood p23 pine) + (surface-condition p23 verysmooth) + (treatment p23 glazed) + (available p24) + (colour p24 red) + (wood p24 teak) + (surface-condition p24 smooth) + (treatment p24 varnished) + (available p25) + (colour p25 red) + (surface-condition p25 smooth) + (available p26) + (wood p26 beech) + (treatment p26 glazed) + (available p27) + (colour p27 blue) + (wood p27 mahogany) + (available p28) + (surface-condition p28 smooth) + (treatment p28 varnished) + (available p29) + (colour p29 black) + (wood p29 mahogany) + (surface-condition p29 smooth) + (treatment p29 varnished) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p21.pddl b/data/woodworking-sat08-strips/p21.pddl new file mode 100644 index 00000000..b3b70c2b --- /dev/null +++ b/data/woodworking-sat08-strips/p21.pddl @@ -0,0 +1,91 @@ +; woodworking task with 3 parts and 100% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 406356 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + blue red - acolour + pine oak - awood + p0 p1 p2 - part + b0 b1 - board + s0 s1 s2 s3 s4 s5 s6 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (has-colour glazer0 blue) + (has-colour immersion-varnisher0 blue) + (has-colour immersion-varnisher0 natural) + (empty highspeed-saw0) + (has-colour spray-varnisher0 blue) + (has-colour spray-varnisher0 natural) + (unused p0) + (goalsize p0 small) + (= (spray-varnish-cost p0) 5) + (= (glaze-cost p0) 10) + (= (grind-cost p0) 15) + (= (plane-cost p0) 10) + (unused p1) + (goalsize p1 large) + (= (spray-varnish-cost p1) 15) + (= (glaze-cost p1) 20) + (= (grind-cost p1) 45) + (= (plane-cost p1) 30) + (unused p2) + (goalsize p2 large) + (= (spray-varnish-cost p2) 15) + (= (glaze-cost p2) 20) + (= (grind-cost p2) 45) + (= (plane-cost p2) 30) + (boardsize b0 s1) + (wood b0 oak) + (surface-condition b0 rough) + (available b0) + (boardsize b1 s6) + (wood b1 pine) + (surface-condition b1 rough) + (available b1) + ) + (:goal + (and + (available p0) + (colour p0 natural) + (wood p0 oak) + (surface-condition p0 smooth) + (treatment p0 varnished) + (available p1) + (colour p1 blue) + (treatment p1 varnished) + (available p2) + (wood p2 pine) + (surface-condition p2 smooth) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p22.pddl b/data/woodworking-sat08-strips/p22.pddl new file mode 100644 index 00000000..b4574e20 --- /dev/null +++ b/data/woodworking-sat08-strips/p22.pddl @@ -0,0 +1,129 @@ +; woodworking task with 6 parts and 100% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 93985 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + mauve black blue green - acolour + teak walnut - awood + p0 p1 p2 p3 p4 p5 - part + b0 b1 - board + s0 s1 s2 s3 s4 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (has-colour glazer0 blue) + (has-colour glazer0 green) + (has-colour glazer0 natural) + (has-colour immersion-varnisher0 blue) + (has-colour immersion-varnisher0 mauve) + (has-colour immersion-varnisher0 black) + (empty highspeed-saw0) + (has-colour spray-varnisher0 blue) + (has-colour spray-varnisher0 mauve) + (has-colour spray-varnisher0 black) + (available p0) + (colour p0 green) + (wood p0 walnut) + (surface-condition p0 smooth) + (treatment p0 colourfragments) + (goalsize p0 medium) + (= (spray-varnish-cost p0) 10) + (= (glaze-cost p0) 15) + (= (grind-cost p0) 30) + (= (plane-cost p0) 20) + (unused p1) + (goalsize p1 small) + (= (spray-varnish-cost p1) 5) + (= (glaze-cost p1) 10) + (= (grind-cost p1) 15) + (= (plane-cost p1) 10) + (unused p2) + (goalsize p2 large) + (= (spray-varnish-cost p2) 15) + (= (glaze-cost p2) 20) + (= (grind-cost p2) 45) + (= (plane-cost p2) 30) + (available p3) + (colour p3 blue) + (wood p3 teak) + (surface-condition p3 verysmooth) + (treatment p3 glazed) + (goalsize p3 large) + (= (spray-varnish-cost p3) 15) + (= (glaze-cost p3) 20) + (= (grind-cost p3) 45) + (= (plane-cost p3) 30) + (unused p4) + (goalsize p4 medium) + (= (spray-varnish-cost p4) 10) + (= (glaze-cost p4) 15) + (= (grind-cost p4) 30) + (= (plane-cost p4) 20) + (unused p5) + (goalsize p5 small) + (= (spray-varnish-cost p5) 5) + (= (glaze-cost p5) 10) + (= (grind-cost p5) 15) + (= (plane-cost p5) 10) + (boardsize b0 s3) + (wood b0 teak) + (surface-condition b0 rough) + (available b0) + (boardsize b1 s4) + (wood b1 walnut) + (surface-condition b1 rough) + (available b1) + ) + (:goal + (and + (available p0) + (colour p0 black) + (wood p0 walnut) + (surface-condition p0 smooth) + (treatment p0 varnished) + (available p1) + (colour p1 green) + (treatment p1 glazed) + (available p2) + (colour p2 natural) + (treatment p2 glazed) + (available p3) + (colour p3 mauve) + (surface-condition p3 smooth) + (treatment p3 varnished) + (available p4) + (colour p4 blue) + (wood p4 teak) + (available p5) + (surface-condition p5 smooth) + (treatment p5 glazed) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p23.pddl b/data/woodworking-sat08-strips/p23.pddl new file mode 100644 index 00000000..2288506f --- /dev/null +++ b/data/woodworking-sat08-strips/p23.pddl @@ -0,0 +1,169 @@ +; woodworking task with 9 parts and 100% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 239783 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + blue black white mauve red green - acolour + oak teak - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 - part + b0 b1 - board + s0 s1 s2 s3 s4 s5 s6 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (has-colour glazer0 blue) + (has-colour glazer0 mauve) + (has-colour glazer0 natural) + (has-colour glazer0 green) + (has-colour glazer0 red) + (has-colour immersion-varnisher0 mauve) + (has-colour immersion-varnisher0 green) + (has-colour immersion-varnisher0 red) + (empty highspeed-saw0) + (has-colour spray-varnisher0 mauve) + (has-colour spray-varnisher0 green) + (has-colour spray-varnisher0 red) + (unused p0) + (goalsize p0 large) + (= (spray-varnish-cost p0) 15) + (= (glaze-cost p0) 20) + (= (grind-cost p0) 45) + (= (plane-cost p0) 30) + (available p1) + (colour p1 white) + (wood p1 teak) + (surface-condition p1 verysmooth) + (treatment p1 glazed) + (goalsize p1 large) + (= (spray-varnish-cost p1) 15) + (= (glaze-cost p1) 20) + (= (grind-cost p1) 45) + (= (plane-cost p1) 30) + (available p2) + (colour p2 mauve) + (wood p2 oak) + (surface-condition p2 smooth) + (treatment p2 colourfragments) + (goalsize p2 small) + (= (spray-varnish-cost p2) 5) + (= (glaze-cost p2) 10) + (= (grind-cost p2) 15) + (= (plane-cost p2) 10) + (available p3) + (colour p3 black) + (wood p3 teak) + (surface-condition p3 verysmooth) + (treatment p3 glazed) + (goalsize p3 large) + (= (spray-varnish-cost p3) 15) + (= (glaze-cost p3) 20) + (= (grind-cost p3) 45) + (= (plane-cost p3) 30) + (available p4) + (colour p4 red) + (wood p4 teak) + (surface-condition p4 verysmooth) + (treatment p4 colourfragments) + (goalsize p4 small) + (= (spray-varnish-cost p4) 5) + (= (glaze-cost p4) 10) + (= (grind-cost p4) 15) + (= (plane-cost p4) 10) + (unused p5) + (goalsize p5 small) + (= (spray-varnish-cost p5) 5) + (= (glaze-cost p5) 10) + (= (grind-cost p5) 15) + (= (plane-cost p5) 10) + (unused p6) + (goalsize p6 small) + (= (spray-varnish-cost p6) 5) + (= (glaze-cost p6) 10) + (= (grind-cost p6) 15) + (= (plane-cost p6) 10) + (unused p7) + (goalsize p7 small) + (= (spray-varnish-cost p7) 5) + (= (glaze-cost p7) 10) + (= (grind-cost p7) 15) + (= (plane-cost p7) 10) + (unused p8) + (goalsize p8 large) + (= (spray-varnish-cost p8) 15) + (= (glaze-cost p8) 20) + (= (grind-cost p8) 45) + (= (plane-cost p8) 30) + (boardsize b0 s6) + (wood b0 teak) + (surface-condition b0 rough) + (available b0) + (boardsize b1 s3) + (wood b1 oak) + (surface-condition b1 rough) + (available b1) + ) + (:goal + (and + (available p0) + (surface-condition p0 smooth) + (treatment p0 varnished) + (available p1) + (colour p1 mauve) + (wood p1 teak) + (available p2) + (colour p2 red) + (wood p2 oak) + (available p3) + (colour p3 natural) + (treatment p3 glazed) + (available p4) + (colour p4 blue) + (wood p4 teak) + (surface-condition p4 smooth) + (treatment p4 glazed) + (available p5) + (colour p5 green) + (wood p5 oak) + (available p6) + (wood p6 oak) + (surface-condition p6 smooth) + (available p7) + (surface-condition p7 verysmooth) + (treatment p7 glazed) + (available p8) + (colour p8 mauve) + (wood p8 teak) + (surface-condition p8 verysmooth) + (treatment p8 varnished) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p24.pddl b/data/woodworking-sat08-strips/p24.pddl new file mode 100644 index 00000000..0b2bc33a --- /dev/null +++ b/data/woodworking-sat08-strips/p24.pddl @@ -0,0 +1,209 @@ +; woodworking task with 12 parts and 100% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 57937 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + mauve white green blue red black - acolour + walnut pine oak - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 - part + b0 b1 b2 b3 - board + s0 s1 s2 s3 s4 s5 s6 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (has-colour glazer0 blue) + (has-colour glazer0 mauve) + (has-colour glazer0 white) + (has-colour glazer0 black) + (has-colour glazer0 red) + (has-colour immersion-varnisher0 blue) + (has-colour immersion-varnisher0 white) + (has-colour immersion-varnisher0 natural) + (has-colour immersion-varnisher0 red) + (empty highspeed-saw0) + (has-colour spray-varnisher0 blue) + (has-colour spray-varnisher0 white) + (has-colour spray-varnisher0 natural) + (has-colour spray-varnisher0 red) + (unused p0) + (goalsize p0 large) + (= (spray-varnish-cost p0) 15) + (= (glaze-cost p0) 20) + (= (grind-cost p0) 45) + (= (plane-cost p0) 30) + (unused p1) + (goalsize p1 medium) + (= (spray-varnish-cost p1) 10) + (= (glaze-cost p1) 15) + (= (grind-cost p1) 30) + (= (plane-cost p1) 20) + (unused p2) + (goalsize p2 large) + (= (spray-varnish-cost p2) 15) + (= (glaze-cost p2) 20) + (= (grind-cost p2) 45) + (= (plane-cost p2) 30) + (unused p3) + (goalsize p3 large) + (= (spray-varnish-cost p3) 15) + (= (glaze-cost p3) 20) + (= (grind-cost p3) 45) + (= (plane-cost p3) 30) + (unused p4) + (goalsize p4 medium) + (= (spray-varnish-cost p4) 10) + (= (glaze-cost p4) 15) + (= (grind-cost p4) 30) + (= (plane-cost p4) 20) + (unused p5) + (goalsize p5 large) + (= (spray-varnish-cost p5) 15) + (= (glaze-cost p5) 20) + (= (grind-cost p5) 45) + (= (plane-cost p5) 30) + (unused p6) + (goalsize p6 small) + (= (spray-varnish-cost p6) 5) + (= (glaze-cost p6) 10) + (= (grind-cost p6) 15) + (= (plane-cost p6) 10) + (available p7) + (colour p7 red) + (wood p7 oak) + (surface-condition p7 rough) + (treatment p7 colourfragments) + (goalsize p7 large) + (= (spray-varnish-cost p7) 15) + (= (glaze-cost p7) 20) + (= (grind-cost p7) 45) + (= (plane-cost p7) 30) + (unused p8) + (goalsize p8 large) + (= (spray-varnish-cost p8) 15) + (= (glaze-cost p8) 20) + (= (grind-cost p8) 45) + (= (plane-cost p8) 30) + (available p9) + (colour p9 mauve) + (wood p9 walnut) + (surface-condition p9 verysmooth) + (treatment p9 varnished) + (goalsize p9 small) + (= (spray-varnish-cost p9) 5) + (= (glaze-cost p9) 10) + (= (grind-cost p9) 15) + (= (plane-cost p9) 10) + (available p10) + (colour p10 green) + (wood p10 pine) + (surface-condition p10 smooth) + (treatment p10 glazed) + (goalsize p10 medium) + (= (spray-varnish-cost p10) 10) + (= (glaze-cost p10) 15) + (= (grind-cost p10) 30) + (= (plane-cost p10) 20) + (unused p11) + (goalsize p11 large) + (= (spray-varnish-cost p11) 15) + (= (glaze-cost p11) 20) + (= (grind-cost p11) 45) + (= (plane-cost p11) 30) + (boardsize b0 s6) + (wood b0 oak) + (surface-condition b0 smooth) + (available b0) + (boardsize b1 s6) + (wood b1 oak) + (surface-condition b1 rough) + (available b1) + (boardsize b2 s5) + (wood b2 pine) + (surface-condition b2 rough) + (available b2) + (boardsize b3 s6) + (wood b3 walnut) + (surface-condition b3 smooth) + (available b3) + ) + (:goal + (and + (available p0) + (surface-condition p0 smooth) + (treatment p0 varnished) + (available p1) + (colour p1 black) + (wood p1 pine) + (surface-condition p1 verysmooth) + (treatment p1 glazed) + (available p2) + (colour p2 blue) + (surface-condition p2 verysmooth) + (available p3) + (colour p3 blue) + (wood p3 oak) + (surface-condition p3 smooth) + (treatment p3 varnished) + (available p4) + (colour p4 mauve) + (wood p4 oak) + (surface-condition p4 verysmooth) + (treatment p4 glazed) + (available p5) + (colour p5 red) + (wood p5 oak) + (surface-condition p5 verysmooth) + (available p6) + (wood p6 oak) + (treatment p6 glazed) + (available p7) + (surface-condition p7 verysmooth) + (treatment p7 varnished) + (available p8) + (colour p8 red) + (wood p8 oak) + (available p9) + (colour p9 white) + (surface-condition p9 verysmooth) + (treatment p9 varnished) + (available p10) + (colour p10 natural) + (wood p10 pine) + (surface-condition p10 smooth) + (treatment p10 varnished) + (available p11) + (colour p11 white) + (surface-condition p11 smooth) + (treatment p11 glazed) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p25.pddl b/data/woodworking-sat08-strips/p25.pddl new file mode 100644 index 00000000..4a4ad396 --- /dev/null +++ b/data/woodworking-sat08-strips/p25.pddl @@ -0,0 +1,249 @@ +; woodworking task with 15 parts and 100% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 224661 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + green blue white red mauve black - acolour + oak cherry walnut teak - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 - part + b0 b1 b2 b3 b4 - board + s0 s1 s2 s3 s4 s5 s6 s7 s8 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (boardsize-successor s7 s8) + (has-colour glazer0 green) + (has-colour glazer0 white) + (has-colour glazer0 natural) + (has-colour glazer0 black) + (has-colour immersion-varnisher0 blue) + (has-colour immersion-varnisher0 mauve) + (has-colour immersion-varnisher0 white) + (has-colour immersion-varnisher0 natural) + (has-colour immersion-varnisher0 black) + (empty highspeed-saw0) + (has-colour spray-varnisher0 blue) + (has-colour spray-varnisher0 mauve) + (has-colour spray-varnisher0 white) + (has-colour spray-varnisher0 natural) + (has-colour spray-varnisher0 black) + (unused p0) + (goalsize p0 large) + (= (spray-varnish-cost p0) 15) + (= (glaze-cost p0) 20) + (= (grind-cost p0) 45) + (= (plane-cost p0) 30) + (unused p1) + (goalsize p1 medium) + (= (spray-varnish-cost p1) 10) + (= (glaze-cost p1) 15) + (= (grind-cost p1) 30) + (= (plane-cost p1) 20) + (unused p2) + (goalsize p2 small) + (= (spray-varnish-cost p2) 5) + (= (glaze-cost p2) 10) + (= (grind-cost p2) 15) + (= (plane-cost p2) 10) + (available p3) + (colour p3 green) + (wood p3 teak) + (surface-condition p3 rough) + (treatment p3 varnished) + (goalsize p3 large) + (= (spray-varnish-cost p3) 15) + (= (glaze-cost p3) 20) + (= (grind-cost p3) 45) + (= (plane-cost p3) 30) + (available p4) + (colour p4 blue) + (wood p4 teak) + (surface-condition p4 rough) + (treatment p4 colourfragments) + (goalsize p4 small) + (= (spray-varnish-cost p4) 5) + (= (glaze-cost p4) 10) + (= (grind-cost p4) 15) + (= (plane-cost p4) 10) + (unused p5) + (goalsize p5 small) + (= (spray-varnish-cost p5) 5) + (= (glaze-cost p5) 10) + (= (grind-cost p5) 15) + (= (plane-cost p5) 10) + (unused p6) + (goalsize p6 medium) + (= (spray-varnish-cost p6) 10) + (= (glaze-cost p6) 15) + (= (grind-cost p6) 30) + (= (plane-cost p6) 20) + (unused p7) + (goalsize p7 large) + (= (spray-varnish-cost p7) 15) + (= (glaze-cost p7) 20) + (= (grind-cost p7) 45) + (= (plane-cost p7) 30) + (unused p8) + (goalsize p8 large) + (= (spray-varnish-cost p8) 15) + (= (glaze-cost p8) 20) + (= (grind-cost p8) 45) + (= (plane-cost p8) 30) + (unused p9) + (goalsize p9 small) + (= (spray-varnish-cost p9) 5) + (= (glaze-cost p9) 10) + (= (grind-cost p9) 15) + (= (plane-cost p9) 10) + (available p10) + (colour p10 white) + (wood p10 walnut) + (surface-condition p10 smooth) + (treatment p10 colourfragments) + (goalsize p10 small) + (= (spray-varnish-cost p10) 5) + (= (glaze-cost p10) 10) + (= (grind-cost p10) 15) + (= (plane-cost p10) 10) + (unused p11) + (goalsize p11 large) + (= (spray-varnish-cost p11) 15) + (= (glaze-cost p11) 20) + (= (grind-cost p11) 45) + (= (plane-cost p11) 30) + (unused p12) + (goalsize p12 medium) + (= (spray-varnish-cost p12) 10) + (= (glaze-cost p12) 15) + (= (grind-cost p12) 30) + (= (plane-cost p12) 20) + (unused p13) + (goalsize p13 large) + (= (spray-varnish-cost p13) 15) + (= (glaze-cost p13) 20) + (= (grind-cost p13) 45) + (= (plane-cost p13) 30) + (unused p14) + (goalsize p14 medium) + (= (spray-varnish-cost p14) 10) + (= (glaze-cost p14) 15) + (= (grind-cost p14) 30) + (= (plane-cost p14) 20) + (boardsize b0 s5) + (wood b0 cherry) + (surface-condition b0 rough) + (available b0) + (boardsize b1 s3) + (wood b1 cherry) + (surface-condition b1 rough) + (available b1) + (boardsize b2 s7) + (wood b2 oak) + (surface-condition b2 smooth) + (available b2) + (boardsize b3 s3) + (wood b3 oak) + (surface-condition b3 rough) + (available b3) + (boardsize b4 s8) + (wood b4 teak) + (surface-condition b4 rough) + (available b4) + ) + (:goal + (and + (available p0) + (colour p0 mauve) + (wood p0 oak) + (surface-condition p0 smooth) + (treatment p0 varnished) + (available p1) + (surface-condition p1 smooth) + (treatment p1 glazed) + (available p2) + (wood p2 cherry) + (surface-condition p2 smooth) + (treatment p2 glazed) + (available p3) + (wood p3 teak) + (treatment p3 glazed) + (available p4) + (colour p4 white) + (wood p4 teak) + (surface-condition p4 smooth) + (available p5) + (colour p5 natural) + (wood p5 cherry) + (surface-condition p5 smooth) + (treatment p5 varnished) + (available p6) + (colour p6 green) + (wood p6 oak) + (surface-condition p6 smooth) + (treatment p6 glazed) + (available p7) + (colour p7 white) + (wood p7 teak) + (treatment p7 varnished) + (available p8) + (colour p8 green) + (surface-condition p8 smooth) + (treatment p8 glazed) + (available p9) + (colour p9 white) + (treatment p9 varnished) + (available p10) + (colour p10 natural) + (wood p10 walnut) + (surface-condition p10 smooth) + (treatment p10 glazed) + (available p11) + (colour p11 black) + (wood p11 teak) + (surface-condition p11 smooth) + (available p12) + (colour p12 blue) + (wood p12 teak) + (surface-condition p12 verysmooth) + (treatment p12 varnished) + (available p13) + (colour p13 white) + (wood p13 cherry) + (available p14) + (colour p14 natural) + (wood p14 oak) + (surface-condition p14 smooth) + (treatment p14 glazed) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p26.pddl b/data/woodworking-sat08-strips/p26.pddl new file mode 100644 index 00000000..c201e23b --- /dev/null +++ b/data/woodworking-sat08-strips/p26.pddl @@ -0,0 +1,280 @@ +; woodworking task with 18 parts and 100% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 518346 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + white red mauve black blue green - acolour + walnut beech cherry mahogany pine - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 - part + b0 b1 b2 b3 b4 b5 b6 - board + s0 s1 s2 s3 s4 s5 s6 s7 s8 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (boardsize-successor s7 s8) + (has-colour glazer0 blue) + (has-colour glazer0 black) + (has-colour glazer0 natural) + (has-colour glazer0 red) + (has-colour immersion-varnisher0 blue) + (has-colour immersion-varnisher0 mauve) + (has-colour immersion-varnisher0 white) + (has-colour immersion-varnisher0 red) + (empty highspeed-saw0) + (has-colour spray-varnisher0 blue) + (has-colour spray-varnisher0 mauve) + (has-colour spray-varnisher0 white) + (has-colour spray-varnisher0 red) + (available p0) + (colour p0 black) + (wood p0 pine) + (surface-condition p0 rough) + (treatment p0 varnished) + (goalsize p0 medium) + (= (spray-varnish-cost p0) 10) + (= (glaze-cost p0) 15) + (= (grind-cost p0) 30) + (= (plane-cost p0) 20) + (unused p1) + (goalsize p1 small) + (= (spray-varnish-cost p1) 5) + (= (glaze-cost p1) 10) + (= (grind-cost p1) 15) + (= (plane-cost p1) 10) + (unused p2) + (goalsize p2 medium) + (= (spray-varnish-cost p2) 10) + (= (glaze-cost p2) 15) + (= (grind-cost p2) 30) + (= (plane-cost p2) 20) + (available p3) + (colour p3 black) + (wood p3 beech) + (surface-condition p3 verysmooth) + (treatment p3 glazed) + (goalsize p3 small) + (= (spray-varnish-cost p3) 5) + (= (glaze-cost p3) 10) + (= (grind-cost p3) 15) + (= (plane-cost p3) 10) + (unused p4) + (goalsize p4 small) + (= (spray-varnish-cost p4) 5) + (= (glaze-cost p4) 10) + (= (grind-cost p4) 15) + (= (plane-cost p4) 10) + (unused p5) + (goalsize p5 large) + (= (spray-varnish-cost p5) 15) + (= (glaze-cost p5) 20) + (= (grind-cost p5) 45) + (= (plane-cost p5) 30) + (unused p6) + (goalsize p6 large) + (= (spray-varnish-cost p6) 15) + (= (glaze-cost p6) 20) + (= (grind-cost p6) 45) + (= (plane-cost p6) 30) + (unused p7) + (goalsize p7 medium) + (= (spray-varnish-cost p7) 10) + (= (glaze-cost p7) 15) + (= (grind-cost p7) 30) + (= (plane-cost p7) 20) + (unused p8) + (goalsize p8 small) + (= (spray-varnish-cost p8) 5) + (= (glaze-cost p8) 10) + (= (grind-cost p8) 15) + (= (plane-cost p8) 10) + (unused p9) + (goalsize p9 small) + (= (spray-varnish-cost p9) 5) + (= (glaze-cost p9) 10) + (= (grind-cost p9) 15) + (= (plane-cost p9) 10) + (unused p10) + (goalsize p10 small) + (= (spray-varnish-cost p10) 5) + (= (glaze-cost p10) 10) + (= (grind-cost p10) 15) + (= (plane-cost p10) 10) + (unused p11) + (goalsize p11 medium) + (= (spray-varnish-cost p11) 10) + (= (glaze-cost p11) 15) + (= (grind-cost p11) 30) + (= (plane-cost p11) 20) + (available p12) + (colour p12 blue) + (wood p12 pine) + (surface-condition p12 verysmooth) + (treatment p12 colourfragments) + (goalsize p12 small) + (= (spray-varnish-cost p12) 5) + (= (glaze-cost p12) 10) + (= (grind-cost p12) 15) + (= (plane-cost p12) 10) + (unused p13) + (goalsize p13 small) + (= (spray-varnish-cost p13) 5) + (= (glaze-cost p13) 10) + (= (grind-cost p13) 15) + (= (plane-cost p13) 10) + (unused p14) + (goalsize p14 small) + (= (spray-varnish-cost p14) 5) + (= (glaze-cost p14) 10) + (= (grind-cost p14) 15) + (= (plane-cost p14) 10) + (unused p15) + (goalsize p15 medium) + (= (spray-varnish-cost p15) 10) + (= (glaze-cost p15) 15) + (= (grind-cost p15) 30) + (= (plane-cost p15) 20) + (unused p16) + (goalsize p16 large) + (= (spray-varnish-cost p16) 15) + (= (glaze-cost p16) 20) + (= (grind-cost p16) 45) + (= (plane-cost p16) 30) + (available p17) + (colour p17 black) + (wood p17 mahogany) + (surface-condition p17 smooth) + (treatment p17 varnished) + (goalsize p17 medium) + (= (spray-varnish-cost p17) 10) + (= (glaze-cost p17) 15) + (= (grind-cost p17) 30) + (= (plane-cost p17) 20) + (boardsize b0 s5) + (wood b0 beech) + (surface-condition b0 rough) + (available b0) + (boardsize b1 s3) + (wood b1 cherry) + (surface-condition b1 rough) + (available b1) + (boardsize b2 s1) + (wood b2 mahogany) + (surface-condition b2 rough) + (available b2) + (boardsize b3 s8) + (wood b3 pine) + (surface-condition b3 rough) + (available b3) + (boardsize b4 s0) + (wood b4 pine) + (surface-condition b4 rough) + (available b4) + (boardsize b5 s3) + (wood b5 walnut) + (surface-condition b5 rough) + (available b5) + (boardsize b6 s4) + (wood b6 walnut) + (surface-condition b6 rough) + (available b6) + ) + (:goal + (and + (available p0) + (surface-condition p0 verysmooth) + (treatment p0 glazed) + (available p1) + (colour p1 red) + (surface-condition p1 verysmooth) + (available p2) + (wood p2 pine) + (surface-condition p2 verysmooth) + (available p3) + (surface-condition p3 smooth) + (treatment p3 glazed) + (available p4) + (colour p4 blue) + (surface-condition p4 smooth) + (available p5) + (wood p5 cherry) + (surface-condition p5 verysmooth) + (available p6) + (wood p6 pine) + (surface-condition p6 smooth) + (available p7) + (colour p7 blue) + (wood p7 walnut) + (surface-condition p7 verysmooth) + (available p8) + (colour p8 mauve) + (wood p8 walnut) + (surface-condition p8 verysmooth) + (treatment p8 varnished) + (available p9) + (wood p9 walnut) + (treatment p9 glazed) + (available p10) + (colour p10 mauve) + (surface-condition p10 verysmooth) + (treatment p10 varnished) + (available p11) + (colour p11 black) + (wood p11 pine) + (surface-condition p11 verysmooth) + (treatment p11 glazed) + (available p12) + (colour p12 white) + (treatment p12 varnished) + (available p13) + (wood p13 walnut) + (surface-condition p13 verysmooth) + (treatment p13 varnished) + (available p14) + (colour p14 white) + (treatment p14 varnished) + (available p15) + (colour p15 red) + (wood p15 beech) + (available p16) + (colour p16 blue) + (wood p16 beech) + (surface-condition p16 smooth) + (treatment p16 glazed) + (available p17) + (colour p17 natural) + (wood p17 mahogany) + (surface-condition p17 verysmooth) + (treatment p17 glazed) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p27.pddl b/data/woodworking-sat08-strips/p27.pddl new file mode 100644 index 00000000..44050baa --- /dev/null +++ b/data/woodworking-sat08-strips/p27.pddl @@ -0,0 +1,320 @@ +; woodworking task with 21 parts and 100% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 8878 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + red blue black mauve white green - acolour + oak pine cherry teak beech - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 p18 p19 p20 - part + b0 b1 b2 b3 b4 b5 - board + s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (boardsize-successor s7 s8) + (boardsize-successor s8 s9) + (has-colour glazer0 blue) + (has-colour glazer0 natural) + (has-colour glazer0 mauve) + (has-colour glazer0 green) + (has-colour glazer0 white) + (has-colour glazer0 red) + (has-colour immersion-varnisher0 blue) + (has-colour immersion-varnisher0 natural) + (has-colour immersion-varnisher0 mauve) + (has-colour immersion-varnisher0 green) + (has-colour immersion-varnisher0 black) + (has-colour immersion-varnisher0 red) + (empty highspeed-saw0) + (has-colour spray-varnisher0 blue) + (has-colour spray-varnisher0 natural) + (has-colour spray-varnisher0 mauve) + (has-colour spray-varnisher0 green) + (has-colour spray-varnisher0 black) + (has-colour spray-varnisher0 red) + (available p0) + (colour p0 red) + (wood p0 pine) + (surface-condition p0 rough) + (treatment p0 varnished) + (goalsize p0 small) + (= (spray-varnish-cost p0) 5) + (= (glaze-cost p0) 10) + (= (grind-cost p0) 15) + (= (plane-cost p0) 10) + (unused p1) + (goalsize p1 medium) + (= (spray-varnish-cost p1) 10) + (= (glaze-cost p1) 15) + (= (grind-cost p1) 30) + (= (plane-cost p1) 20) + (unused p2) + (goalsize p2 large) + (= (spray-varnish-cost p2) 15) + (= (glaze-cost p2) 20) + (= (grind-cost p2) 45) + (= (plane-cost p2) 30) + (available p3) + (colour p3 red) + (wood p3 oak) + (surface-condition p3 verysmooth) + (treatment p3 glazed) + (goalsize p3 medium) + (= (spray-varnish-cost p3) 10) + (= (glaze-cost p3) 15) + (= (grind-cost p3) 30) + (= (plane-cost p3) 20) + (unused p4) + (goalsize p4 large) + (= (spray-varnish-cost p4) 15) + (= (glaze-cost p4) 20) + (= (grind-cost p4) 45) + (= (plane-cost p4) 30) + (unused p5) + (goalsize p5 small) + (= (spray-varnish-cost p5) 5) + (= (glaze-cost p5) 10) + (= (grind-cost p5) 15) + (= (plane-cost p5) 10) + (unused p6) + (goalsize p6 small) + (= (spray-varnish-cost p6) 5) + (= (glaze-cost p6) 10) + (= (grind-cost p6) 15) + (= (plane-cost p6) 10) + (unused p7) + (goalsize p7 medium) + (= (spray-varnish-cost p7) 10) + (= (glaze-cost p7) 15) + (= (grind-cost p7) 30) + (= (plane-cost p7) 20) + (unused p8) + (goalsize p8 large) + (= (spray-varnish-cost p8) 15) + (= (glaze-cost p8) 20) + (= (grind-cost p8) 45) + (= (plane-cost p8) 30) + (unused p9) + (goalsize p9 large) + (= (spray-varnish-cost p9) 15) + (= (glaze-cost p9) 20) + (= (grind-cost p9) 45) + (= (plane-cost p9) 30) + (unused p10) + (goalsize p10 large) + (= (spray-varnish-cost p10) 15) + (= (glaze-cost p10) 20) + (= (grind-cost p10) 45) + (= (plane-cost p10) 30) + (unused p11) + (goalsize p11 large) + (= (spray-varnish-cost p11) 15) + (= (glaze-cost p11) 20) + (= (grind-cost p11) 45) + (= (plane-cost p11) 30) + (available p12) + (colour p12 white) + (wood p12 cherry) + (surface-condition p12 smooth) + (treatment p12 glazed) + (goalsize p12 large) + (= (spray-varnish-cost p12) 15) + (= (glaze-cost p12) 20) + (= (grind-cost p12) 45) + (= (plane-cost p12) 30) + (available p13) + (colour p13 white) + (wood p13 pine) + (surface-condition p13 smooth) + (treatment p13 varnished) + (goalsize p13 small) + (= (spray-varnish-cost p13) 5) + (= (glaze-cost p13) 10) + (= (grind-cost p13) 15) + (= (plane-cost p13) 10) + (available p14) + (colour p14 black) + (wood p14 cherry) + (surface-condition p14 smooth) + (treatment p14 glazed) + (goalsize p14 small) + (= (spray-varnish-cost p14) 5) + (= (glaze-cost p14) 10) + (= (grind-cost p14) 15) + (= (plane-cost p14) 10) + (unused p15) + (goalsize p15 large) + (= (spray-varnish-cost p15) 15) + (= (glaze-cost p15) 20) + (= (grind-cost p15) 45) + (= (plane-cost p15) 30) + (available p16) + (colour p16 white) + (wood p16 oak) + (surface-condition p16 rough) + (treatment p16 varnished) + (goalsize p16 large) + (= (spray-varnish-cost p16) 15) + (= (glaze-cost p16) 20) + (= (grind-cost p16) 45) + (= (plane-cost p16) 30) + (unused p17) + (goalsize p17 large) + (= (spray-varnish-cost p17) 15) + (= (glaze-cost p17) 20) + (= (grind-cost p17) 45) + (= (plane-cost p17) 30) + (unused p18) + (goalsize p18 small) + (= (spray-varnish-cost p18) 5) + (= (glaze-cost p18) 10) + (= (grind-cost p18) 15) + (= (plane-cost p18) 10) + (available p19) + (colour p19 black) + (wood p19 cherry) + (surface-condition p19 verysmooth) + (treatment p19 varnished) + (goalsize p19 medium) + (= (spray-varnish-cost p19) 10) + (= (glaze-cost p19) 15) + (= (grind-cost p19) 30) + (= (plane-cost p19) 20) + (unused p20) + (goalsize p20 medium) + (= (spray-varnish-cost p20) 10) + (= (glaze-cost p20) 15) + (= (grind-cost p20) 30) + (= (plane-cost p20) 20) + (boardsize b0 s9) + (wood b0 beech) + (surface-condition b0 rough) + (available b0) + (boardsize b1 s7) + (wood b1 cherry) + (surface-condition b1 rough) + (available b1) + (boardsize b2 s2) + (wood b2 cherry) + (surface-condition b2 smooth) + (available b2) + (boardsize b3 s5) + (wood b3 oak) + (surface-condition b3 smooth) + (available b3) + (boardsize b4 s8) + (wood b4 pine) + (surface-condition b4 rough) + (available b4) + (boardsize b5 s2) + (wood b5 teak) + (surface-condition b5 rough) + (available b5) + ) + (:goal + (and + (available p0) + (colour p0 natural) + (surface-condition p0 smooth) + (available p1) + (colour p1 green) + (wood p1 pine) + (surface-condition p1 smooth) + (treatment p1 varnished) + (available p2) + (colour p2 natural) + (wood p2 cherry) + (available p3) + (colour p3 white) + (treatment p3 glazed) + (available p4) + (colour p4 mauve) + (surface-condition p4 smooth) + (available p5) + (colour p5 green) + (surface-condition p5 verysmooth) + (available p6) + (colour p6 black) + (wood p6 oak) + (surface-condition p6 smooth) + (treatment p6 varnished) + (available p7) + (colour p7 blue) + (wood p7 teak) + (available p8) + (colour p8 mauve) + (wood p8 beech) + (treatment p8 varnished) + (available p9) + (colour p9 mauve) + (treatment p9 glazed) + (available p10) + (wood p10 oak) + (treatment p10 varnished) + (available p11) + (colour p11 natural) + (treatment p11 glazed) + (available p12) + (wood p12 cherry) + (surface-condition p12 verysmooth) + (treatment p12 varnished) + (available p13) + (colour p13 red) + (wood p13 pine) + (surface-condition p13 verysmooth) + (available p14) + (colour p14 blue) + (wood p14 cherry) + (surface-condition p14 verysmooth) + (treatment p14 glazed) + (available p15) + (wood p15 beech) + (treatment p15 glazed) + (available p16) + (surface-condition p16 smooth) + (treatment p16 glazed) + (available p17) + (colour p17 blue) + (treatment p17 varnished) + (available p18) + (wood p18 cherry) + (surface-condition p18 verysmooth) + (available p19) + (colour p19 natural) + (wood p19 cherry) + (available p20) + (colour p20 blue) + (surface-condition p20 smooth) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p28.pddl b/data/woodworking-sat08-strips/p28.pddl new file mode 100644 index 00000000..1ada6699 --- /dev/null +++ b/data/woodworking-sat08-strips/p28.pddl @@ -0,0 +1,352 @@ +; woodworking task with 24 parts and 100% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 660554 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + white blue green mauve red black - acolour + mahogany beech cherry pine oak teak - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 p18 p19 p20 p21 p22 p23 - part + b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 - board + s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (boardsize-successor s7 s8) + (boardsize-successor s8 s9) + (has-colour glazer0 blue) + (has-colour glazer0 mauve) + (has-colour glazer0 white) + (has-colour glazer0 natural) + (has-colour glazer0 green) + (has-colour immersion-varnisher0 blue) + (has-colour immersion-varnisher0 natural) + (has-colour immersion-varnisher0 mauve) + (has-colour immersion-varnisher0 green) + (has-colour immersion-varnisher0 black) + (has-colour immersion-varnisher0 white) + (has-colour immersion-varnisher0 red) + (empty highspeed-saw0) + (has-colour spray-varnisher0 blue) + (has-colour spray-varnisher0 natural) + (has-colour spray-varnisher0 mauve) + (has-colour spray-varnisher0 green) + (has-colour spray-varnisher0 black) + (has-colour spray-varnisher0 white) + (has-colour spray-varnisher0 red) + (unused p0) + (goalsize p0 small) + (= (spray-varnish-cost p0) 5) + (= (glaze-cost p0) 10) + (= (grind-cost p0) 15) + (= (plane-cost p0) 10) + (unused p1) + (goalsize p1 medium) + (= (spray-varnish-cost p1) 10) + (= (glaze-cost p1) 15) + (= (grind-cost p1) 30) + (= (plane-cost p1) 20) + (unused p2) + (goalsize p2 medium) + (= (spray-varnish-cost p2) 10) + (= (glaze-cost p2) 15) + (= (grind-cost p2) 30) + (= (plane-cost p2) 20) + (unused p3) + (goalsize p3 medium) + (= (spray-varnish-cost p3) 10) + (= (glaze-cost p3) 15) + (= (grind-cost p3) 30) + (= (plane-cost p3) 20) + (unused p4) + (goalsize p4 large) + (= (spray-varnish-cost p4) 15) + (= (glaze-cost p4) 20) + (= (grind-cost p4) 45) + (= (plane-cost p4) 30) + (unused p5) + (goalsize p5 large) + (= (spray-varnish-cost p5) 15) + (= (glaze-cost p5) 20) + (= (grind-cost p5) 45) + (= (plane-cost p5) 30) + (unused p6) + (goalsize p6 medium) + (= (spray-varnish-cost p6) 10) + (= (glaze-cost p6) 15) + (= (grind-cost p6) 30) + (= (plane-cost p6) 20) + (unused p7) + (goalsize p7 large) + (= (spray-varnish-cost p7) 15) + (= (glaze-cost p7) 20) + (= (grind-cost p7) 45) + (= (plane-cost p7) 30) + (unused p8) + (goalsize p8 large) + (= (spray-varnish-cost p8) 15) + (= (glaze-cost p8) 20) + (= (grind-cost p8) 45) + (= (plane-cost p8) 30) + (available p9) + (colour p9 white) + (wood p9 cherry) + (surface-condition p9 smooth) + (treatment p9 colourfragments) + (goalsize p9 large) + (= (spray-varnish-cost p9) 15) + (= (glaze-cost p9) 20) + (= (grind-cost p9) 45) + (= (plane-cost p9) 30) + (unused p10) + (goalsize p10 small) + (= (spray-varnish-cost p10) 5) + (= (glaze-cost p10) 10) + (= (grind-cost p10) 15) + (= (plane-cost p10) 10) + (unused p11) + (goalsize p11 medium) + (= (spray-varnish-cost p11) 10) + (= (glaze-cost p11) 15) + (= (grind-cost p11) 30) + (= (plane-cost p11) 20) + (unused p12) + (goalsize p12 small) + (= (spray-varnish-cost p12) 5) + (= (glaze-cost p12) 10) + (= (grind-cost p12) 15) + (= (plane-cost p12) 10) + (unused p13) + (goalsize p13 small) + (= (spray-varnish-cost p13) 5) + (= (glaze-cost p13) 10) + (= (grind-cost p13) 15) + (= (plane-cost p13) 10) + (unused p14) + (goalsize p14 large) + (= (spray-varnish-cost p14) 15) + (= (glaze-cost p14) 20) + (= (grind-cost p14) 45) + (= (plane-cost p14) 30) + (unused p15) + (goalsize p15 small) + (= (spray-varnish-cost p15) 5) + (= (glaze-cost p15) 10) + (= (grind-cost p15) 15) + (= (plane-cost p15) 10) + (unused p16) + (goalsize p16 small) + (= (spray-varnish-cost p16) 5) + (= (glaze-cost p16) 10) + (= (grind-cost p16) 15) + (= (plane-cost p16) 10) + (unused p17) + (goalsize p17 large) + (= (spray-varnish-cost p17) 15) + (= (glaze-cost p17) 20) + (= (grind-cost p17) 45) + (= (plane-cost p17) 30) + (unused p18) + (goalsize p18 medium) + (= (spray-varnish-cost p18) 10) + (= (glaze-cost p18) 15) + (= (grind-cost p18) 30) + (= (plane-cost p18) 20) + (unused p19) + (goalsize p19 small) + (= (spray-varnish-cost p19) 5) + (= (glaze-cost p19) 10) + (= (grind-cost p19) 15) + (= (plane-cost p19) 10) + (available p20) + (colour p20 blue) + (wood p20 pine) + (surface-condition p20 verysmooth) + (treatment p20 glazed) + (goalsize p20 large) + (= (spray-varnish-cost p20) 15) + (= (glaze-cost p20) 20) + (= (grind-cost p20) 45) + (= (plane-cost p20) 30) + (unused p21) + (goalsize p21 large) + (= (spray-varnish-cost p21) 15) + (= (glaze-cost p21) 20) + (= (grind-cost p21) 45) + (= (plane-cost p21) 30) + (unused p22) + (goalsize p22 medium) + (= (spray-varnish-cost p22) 10) + (= (glaze-cost p22) 15) + (= (grind-cost p22) 30) + (= (plane-cost p22) 20) + (unused p23) + (goalsize p23 large) + (= (spray-varnish-cost p23) 15) + (= (glaze-cost p23) 20) + (= (grind-cost p23) 45) + (= (plane-cost p23) 30) + (boardsize b0 s7) + (wood b0 cherry) + (surface-condition b0 rough) + (available b0) + (boardsize b1 s7) + (wood b1 cherry) + (surface-condition b1 rough) + (available b1) + (boardsize b2 s0) + (wood b2 cherry) + (surface-condition b2 smooth) + (available b2) + (boardsize b3 s9) + (wood b3 mahogany) + (surface-condition b3 rough) + (available b3) + (boardsize b4 s0) + (wood b4 mahogany) + (surface-condition b4 rough) + (available b4) + (boardsize b5 s6) + (wood b5 oak) + (surface-condition b5 rough) + (available b5) + (boardsize b6 s1) + (wood b6 oak) + (surface-condition b6 rough) + (available b6) + (boardsize b7 s5) + (wood b7 pine) + (surface-condition b7 rough) + (available b7) + (boardsize b8 s6) + (wood b8 teak) + (surface-condition b8 rough) + (available b8) + (boardsize b9 s4) + (wood b9 beech) + (surface-condition b9 rough) + (available b9) + ) + (:goal + (and + (available p0) + (colour p0 mauve) + (wood p0 oak) + (surface-condition p0 smooth) + (treatment p0 glazed) + (available p1) + (wood p1 oak) + (treatment p1 varnished) + (available p2) + (colour p2 red) + (treatment p2 varnished) + (available p3) + (wood p3 oak) + (treatment p3 varnished) + (available p4) + (colour p4 green) + (wood p4 mahogany) + (available p5) + (wood p5 mahogany) + (surface-condition p5 verysmooth) + (available p6) + (colour p6 blue) + (wood p6 cherry) + (available p7) + (colour p7 white) + (surface-condition p7 verysmooth) + (available p8) + (colour p8 green) + (wood p8 teak) + (surface-condition p8 smooth) + (treatment p8 varnished) + (available p9) + (colour p9 mauve) + (wood p9 cherry) + (surface-condition p9 smooth) + (treatment p9 glazed) + (available p10) + (colour p10 blue) + (surface-condition p10 smooth) + (available p11) + (colour p11 natural) + (treatment p11 varnished) + (available p12) + (wood p12 cherry) + (surface-condition p12 verysmooth) + (available p13) + (colour p13 white) + (surface-condition p13 smooth) + (treatment p13 varnished) + (available p14) + (colour p14 mauve) + (surface-condition p14 verysmooth) + (treatment p14 varnished) + (available p15) + (surface-condition p15 verysmooth) + (treatment p15 glazed) + (available p16) + (surface-condition p16 smooth) + (treatment p16 varnished) + (available p17) + (colour p17 black) + (wood p17 teak) + (surface-condition p17 verysmooth) + (treatment p17 varnished) + (available p18) + (colour p18 mauve) + (wood p18 cherry) + (treatment p18 glazed) + (available p19) + (surface-condition p19 verysmooth) + (treatment p19 glazed) + (available p20) + (colour p20 red) + (wood p20 pine) + (surface-condition p20 smooth) + (treatment p20 varnished) + (available p21) + (colour p21 natural) + (surface-condition p21 verysmooth) + (available p22) + (colour p22 natural) + (wood p22 mahogany) + (surface-condition p22 smooth) + (treatment p22 glazed) + (available p23) + (colour p23 green) + (wood p23 cherry) + (surface-condition p23 smooth) + (treatment p23 glazed) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p29.pddl b/data/woodworking-sat08-strips/p29.pddl new file mode 100644 index 00000000..f5f6f99f --- /dev/null +++ b/data/woodworking-sat08-strips/p29.pddl @@ -0,0 +1,393 @@ +; woodworking task with 27 parts and 100% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 484690 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + white green blue black mauve red - acolour + beech teak walnut mahogany pine oak cherry - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 p18 p19 p20 p21 p22 p23 p24 p25 p26 - part + b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 - board + s0 s1 s2 s3 s4 s5 s6 s7 s8 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (boardsize-successor s7 s8) + (has-colour glazer0 blue) + (has-colour glazer0 natural) + (has-colour glazer0 mauve) + (has-colour glazer0 green) + (has-colour glazer0 black) + (has-colour glazer0 white) + (has-colour immersion-varnisher0 blue) + (has-colour immersion-varnisher0 natural) + (has-colour immersion-varnisher0 mauve) + (has-colour immersion-varnisher0 green) + (has-colour immersion-varnisher0 white) + (has-colour immersion-varnisher0 red) + (empty highspeed-saw0) + (has-colour spray-varnisher0 blue) + (has-colour spray-varnisher0 natural) + (has-colour spray-varnisher0 mauve) + (has-colour spray-varnisher0 green) + (has-colour spray-varnisher0 white) + (has-colour spray-varnisher0 red) + (unused p0) + (goalsize p0 small) + (= (spray-varnish-cost p0) 5) + (= (glaze-cost p0) 10) + (= (grind-cost p0) 15) + (= (plane-cost p0) 10) + (available p1) + (colour p1 green) + (wood p1 oak) + (surface-condition p1 smooth) + (treatment p1 varnished) + (goalsize p1 large) + (= (spray-varnish-cost p1) 15) + (= (glaze-cost p1) 20) + (= (grind-cost p1) 45) + (= (plane-cost p1) 30) + (unused p2) + (goalsize p2 medium) + (= (spray-varnish-cost p2) 10) + (= (glaze-cost p2) 15) + (= (grind-cost p2) 30) + (= (plane-cost p2) 20) + (unused p3) + (goalsize p3 small) + (= (spray-varnish-cost p3) 5) + (= (glaze-cost p3) 10) + (= (grind-cost p3) 15) + (= (plane-cost p3) 10) + (unused p4) + (goalsize p4 small) + (= (spray-varnish-cost p4) 5) + (= (glaze-cost p4) 10) + (= (grind-cost p4) 15) + (= (plane-cost p4) 10) + (unused p5) + (goalsize p5 medium) + (= (spray-varnish-cost p5) 10) + (= (glaze-cost p5) 15) + (= (grind-cost p5) 30) + (= (plane-cost p5) 20) + (available p6) + (colour p6 white) + (wood p6 beech) + (surface-condition p6 rough) + (treatment p6 colourfragments) + (goalsize p6 large) + (= (spray-varnish-cost p6) 15) + (= (glaze-cost p6) 20) + (= (grind-cost p6) 45) + (= (plane-cost p6) 30) + (available p7) + (colour p7 natural) + (wood p7 oak) + (surface-condition p7 verysmooth) + (treatment p7 colourfragments) + (goalsize p7 medium) + (= (spray-varnish-cost p7) 10) + (= (glaze-cost p7) 15) + (= (grind-cost p7) 30) + (= (plane-cost p7) 20) + (unused p8) + (goalsize p8 medium) + (= (spray-varnish-cost p8) 10) + (= (glaze-cost p8) 15) + (= (grind-cost p8) 30) + (= (plane-cost p8) 20) + (unused p9) + (goalsize p9 small) + (= (spray-varnish-cost p9) 5) + (= (glaze-cost p9) 10) + (= (grind-cost p9) 15) + (= (plane-cost p9) 10) + (unused p10) + (goalsize p10 medium) + (= (spray-varnish-cost p10) 10) + (= (glaze-cost p10) 15) + (= (grind-cost p10) 30) + (= (plane-cost p10) 20) + (unused p11) + (goalsize p11 small) + (= (spray-varnish-cost p11) 5) + (= (glaze-cost p11) 10) + (= (grind-cost p11) 15) + (= (plane-cost p11) 10) + (unused p12) + (goalsize p12 small) + (= (spray-varnish-cost p12) 5) + (= (glaze-cost p12) 10) + (= (grind-cost p12) 15) + (= (plane-cost p12) 10) + (available p13) + (colour p13 black) + (wood p13 walnut) + (surface-condition p13 smooth) + (treatment p13 glazed) + (goalsize p13 large) + (= (spray-varnish-cost p13) 15) + (= (glaze-cost p13) 20) + (= (grind-cost p13) 45) + (= (plane-cost p13) 30) + (unused p14) + (goalsize p14 medium) + (= (spray-varnish-cost p14) 10) + (= (glaze-cost p14) 15) + (= (grind-cost p14) 30) + (= (plane-cost p14) 20) + (unused p15) + (goalsize p15 small) + (= (spray-varnish-cost p15) 5) + (= (glaze-cost p15) 10) + (= (grind-cost p15) 15) + (= (plane-cost p15) 10) + (unused p16) + (goalsize p16 large) + (= (spray-varnish-cost p16) 15) + (= (glaze-cost p16) 20) + (= (grind-cost p16) 45) + (= (plane-cost p16) 30) + (unused p17) + (goalsize p17 small) + (= (spray-varnish-cost p17) 5) + (= (glaze-cost p17) 10) + (= (grind-cost p17) 15) + (= (plane-cost p17) 10) + (unused p18) + (goalsize p18 small) + (= (spray-varnish-cost p18) 5) + (= (glaze-cost p18) 10) + (= (grind-cost p18) 15) + (= (plane-cost p18) 10) + (unused p19) + (goalsize p19 large) + (= (spray-varnish-cost p19) 15) + (= (glaze-cost p19) 20) + (= (grind-cost p19) 45) + (= (plane-cost p19) 30) + (available p20) + (colour p20 mauve) + (wood p20 walnut) + (surface-condition p20 smooth) + (treatment p20 glazed) + (goalsize p20 medium) + (= (spray-varnish-cost p20) 10) + (= (glaze-cost p20) 15) + (= (grind-cost p20) 30) + (= (plane-cost p20) 20) + (unused p21) + (goalsize p21 small) + (= (spray-varnish-cost p21) 5) + (= (glaze-cost p21) 10) + (= (grind-cost p21) 15) + (= (plane-cost p21) 10) + (unused p22) + (goalsize p22 small) + (= (spray-varnish-cost p22) 5) + (= (glaze-cost p22) 10) + (= (grind-cost p22) 15) + (= (plane-cost p22) 10) + (unused p23) + (goalsize p23 medium) + (= (spray-varnish-cost p23) 10) + (= (glaze-cost p23) 15) + (= (grind-cost p23) 30) + (= (plane-cost p23) 20) + (unused p24) + (goalsize p24 medium) + (= (spray-varnish-cost p24) 10) + (= (glaze-cost p24) 15) + (= (grind-cost p24) 30) + (= (plane-cost p24) 20) + (unused p25) + (goalsize p25 small) + (= (spray-varnish-cost p25) 5) + (= (glaze-cost p25) 10) + (= (grind-cost p25) 15) + (= (plane-cost p25) 10) + (unused p26) + (goalsize p26 medium) + (= (spray-varnish-cost p26) 10) + (= (glaze-cost p26) 15) + (= (grind-cost p26) 30) + (= (plane-cost p26) 20) + (boardsize b0 s4) + (wood b0 cherry) + (surface-condition b0 rough) + (available b0) + (boardsize b1 s2) + (wood b1 cherry) + (surface-condition b1 rough) + (available b1) + (boardsize b2 s4) + (wood b2 mahogany) + (surface-condition b2 rough) + (available b2) + (boardsize b3 s2) + (wood b3 mahogany) + (surface-condition b3 rough) + (available b3) + (boardsize b4 s5) + (wood b4 oak) + (surface-condition b4 rough) + (available b4) + (boardsize b5 s4) + (wood b5 oak) + (surface-condition b5 rough) + (available b5) + (boardsize b6 s2) + (wood b6 pine) + (surface-condition b6 smooth) + (available b6) + (boardsize b7 s2) + (wood b7 walnut) + (surface-condition b7 rough) + (available b7) + (boardsize b8 s8) + (wood b8 teak) + (surface-condition b8 rough) + (available b8) + (boardsize b9 s1) + (wood b9 beech) + (surface-condition b9 rough) + (available b9) + ) + (:goal + (and + (available p0) + (wood p0 walnut) + (treatment p0 varnished) + (available p1) + (colour p1 white) + (surface-condition p1 verysmooth) + (treatment p1 glazed) + (available p2) + (colour p2 white) + (wood p2 oak) + (treatment p2 varnished) + (available p3) + (colour p3 blue) + (wood p3 walnut) + (surface-condition p3 smooth) + (available p4) + (colour p4 natural) + (wood p4 mahogany) + (available p5) + (colour p5 blue) + (treatment p5 varnished) + (available p6) + (wood p6 beech) + (surface-condition p6 smooth) + (available p7) + (colour p7 blue) + (treatment p7 glazed) + (available p8) + (colour p8 green) + (surface-condition p8 verysmooth) + (treatment p8 varnished) + (available p9) + (colour p9 natural) + (wood p9 beech) + (surface-condition p9 verysmooth) + (available p10) + (colour p10 natural) + (surface-condition p10 smooth) + (treatment p10 varnished) + (available p11) + (colour p11 natural) + (wood p11 cherry) + (surface-condition p11 verysmooth) + (treatment p11 glazed) + (available p12) + (colour p12 mauve) + (surface-condition p12 smooth) + (available p13) + (colour p13 blue) + (treatment p13 varnished) + (available p14) + (wood p14 teak) + (surface-condition p14 smooth) + (treatment p14 glazed) + (available p15) + (colour p15 green) + (treatment p15 glazed) + (available p16) + (colour p16 blue) + (wood p16 teak) + (surface-condition p16 smooth) + (treatment p16 varnished) + (available p17) + (colour p17 black) + (wood p17 pine) + (treatment p17 glazed) + (available p18) + (colour p18 natural) + (wood p18 oak) + (surface-condition p18 verysmooth) + (treatment p18 varnished) + (available p19) + (colour p19 mauve) + (wood p19 teak) + (surface-condition p19 smooth) + (treatment p19 varnished) + (available p20) + (surface-condition p20 smooth) + (treatment p20 varnished) + (available p21) + (colour p21 natural) + (wood p21 oak) + (surface-condition p21 verysmooth) + (treatment p21 glazed) + (available p22) + (wood p22 cherry) + (surface-condition p22 smooth) + (available p23) + (wood p23 cherry) + (surface-condition p23 smooth) + (treatment p23 glazed) + (available p24) + (colour p24 white) + (surface-condition p24 smooth) + (available p25) + (colour p25 red) + (surface-condition p25 verysmooth) + (treatment p25 varnished) + (available p26) + (colour p26 white) + (wood p26 oak) + (surface-condition p26 smooth) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/data/woodworking-sat08-strips/p30.pddl b/data/woodworking-sat08-strips/p30.pddl new file mode 100644 index 00000000..c456155a --- /dev/null +++ b/data/woodworking-sat08-strips/p30.pddl @@ -0,0 +1,415 @@ +; woodworking task with 30 parts and 100% wood +; Machines: +; 1 grinder +; 1 glazer +; 1 immersion-varnisher +; 1 planer +; 1 highspeed-saw +; 1 spray-varnisher +; 1 saw +; random seed: 473295 + +(define (problem wood-prob) + (:domain woodworking) + (:objects + grinder0 - grinder + glazer0 - glazer + immersion-varnisher0 - immersion-varnisher + planer0 - planer + highspeed-saw0 - highspeed-saw + spray-varnisher0 - spray-varnisher + saw0 - saw + black red blue green mauve white - acolour + walnut mahogany pine beech teak oak cherry - awood + p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 p18 p19 p20 p21 p22 p23 p24 p25 p26 p27 p28 p29 - part + b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 - board + s0 s1 s2 s3 s4 s5 s6 s7 s8 - aboardsize + ) + (:init + (grind-treatment-change varnished colourfragments) + (grind-treatment-change glazed untreated) + (grind-treatment-change untreated untreated) + (grind-treatment-change colourfragments untreated) + (is-smooth smooth) + (is-smooth verysmooth) + (= (total-cost) 0) + (boardsize-successor s0 s1) + (boardsize-successor s1 s2) + (boardsize-successor s2 s3) + (boardsize-successor s3 s4) + (boardsize-successor s4 s5) + (boardsize-successor s5 s6) + (boardsize-successor s6 s7) + (boardsize-successor s7 s8) + (has-colour glazer0 blue) + (has-colour glazer0 natural) + (has-colour glazer0 mauve) + (has-colour glazer0 black) + (has-colour glazer0 green) + (has-colour glazer0 white) + (has-colour glazer0 red) + (has-colour immersion-varnisher0 blue) + (has-colour immersion-varnisher0 natural) + (has-colour immersion-varnisher0 mauve) + (has-colour immersion-varnisher0 green) + (has-colour immersion-varnisher0 black) + (has-colour immersion-varnisher0 white) + (has-colour immersion-varnisher0 red) + (empty highspeed-saw0) + (has-colour spray-varnisher0 blue) + (has-colour spray-varnisher0 natural) + (has-colour spray-varnisher0 mauve) + (has-colour spray-varnisher0 green) + (has-colour spray-varnisher0 black) + (has-colour spray-varnisher0 white) + (has-colour spray-varnisher0 red) + (unused p0) + (goalsize p0 small) + (= (spray-varnish-cost p0) 5) + (= (glaze-cost p0) 10) + (= (grind-cost p0) 15) + (= (plane-cost p0) 10) + (unused p1) + (goalsize p1 small) + (= (spray-varnish-cost p1) 5) + (= (glaze-cost p1) 10) + (= (grind-cost p1) 15) + (= (plane-cost p1) 10) + (unused p2) + (goalsize p2 medium) + (= (spray-varnish-cost p2) 10) + (= (glaze-cost p2) 15) + (= (grind-cost p2) 30) + (= (plane-cost p2) 20) + (unused p3) + (goalsize p3 small) + (= (spray-varnish-cost p3) 5) + (= (glaze-cost p3) 10) + (= (grind-cost p3) 15) + (= (plane-cost p3) 10) + (unused p4) + (goalsize p4 small) + (= (spray-varnish-cost p4) 5) + (= (glaze-cost p4) 10) + (= (grind-cost p4) 15) + (= (plane-cost p4) 10) + (available p5) + (colour p5 mauve) + (wood p5 teak) + (surface-condition p5 rough) + (treatment p5 varnished) + (goalsize p5 medium) + (= (spray-varnish-cost p5) 10) + (= (glaze-cost p5) 15) + (= (grind-cost p5) 30) + (= (plane-cost p5) 20) + (available p6) + (colour p6 mauve) + (wood p6 cherry) + (surface-condition p6 rough) + (treatment p6 colourfragments) + (goalsize p6 large) + (= (spray-varnish-cost p6) 15) + (= (glaze-cost p6) 20) + (= (grind-cost p6) 45) + (= (plane-cost p6) 30) + (unused p7) + (goalsize p7 small) + (= (spray-varnish-cost p7) 5) + (= (glaze-cost p7) 10) + (= (grind-cost p7) 15) + (= (plane-cost p7) 10) + (unused p8) + (goalsize p8 medium) + (= (spray-varnish-cost p8) 10) + (= (glaze-cost p8) 15) + (= (grind-cost p8) 30) + (= (plane-cost p8) 20) + (unused p9) + (goalsize p9 medium) + (= (spray-varnish-cost p9) 10) + (= (glaze-cost p9) 15) + (= (grind-cost p9) 30) + (= (plane-cost p9) 20) + (unused p10) + (goalsize p10 large) + (= (spray-varnish-cost p10) 15) + (= (glaze-cost p10) 20) + (= (grind-cost p10) 45) + (= (plane-cost p10) 30) + (unused p11) + (goalsize p11 medium) + (= (spray-varnish-cost p11) 10) + (= (glaze-cost p11) 15) + (= (grind-cost p11) 30) + (= (plane-cost p11) 20) + (unused p12) + (goalsize p12 small) + (= (spray-varnish-cost p12) 5) + (= (glaze-cost p12) 10) + (= (grind-cost p12) 15) + (= (plane-cost p12) 10) + (unused p13) + (goalsize p13 large) + (= (spray-varnish-cost p13) 15) + (= (glaze-cost p13) 20) + (= (grind-cost p13) 45) + (= (plane-cost p13) 30) + (available p14) + (colour p14 blue) + (wood p14 pine) + (surface-condition p14 smooth) + (treatment p14 colourfragments) + (goalsize p14 medium) + (= (spray-varnish-cost p14) 10) + (= (glaze-cost p14) 15) + (= (grind-cost p14) 30) + (= (plane-cost p14) 20) + (unused p15) + (goalsize p15 medium) + (= (spray-varnish-cost p15) 10) + (= (glaze-cost p15) 15) + (= (grind-cost p15) 30) + (= (plane-cost p15) 20) + (unused p16) + (goalsize p16 medium) + (= (spray-varnish-cost p16) 10) + (= (glaze-cost p16) 15) + (= (grind-cost p16) 30) + (= (plane-cost p16) 20) + (available p17) + (colour p17 natural) + (wood p17 oak) + (surface-condition p17 verysmooth) + (treatment p17 colourfragments) + (goalsize p17 large) + (= (spray-varnish-cost p17) 15) + (= (glaze-cost p17) 20) + (= (grind-cost p17) 45) + (= (plane-cost p17) 30) + (unused p18) + (goalsize p18 large) + (= (spray-varnish-cost p18) 15) + (= (glaze-cost p18) 20) + (= (grind-cost p18) 45) + (= (plane-cost p18) 30) + (unused p19) + (goalsize p19 medium) + (= (spray-varnish-cost p19) 10) + (= (glaze-cost p19) 15) + (= (grind-cost p19) 30) + (= (plane-cost p19) 20) + (unused p20) + (goalsize p20 large) + (= (spray-varnish-cost p20) 15) + (= (glaze-cost p20) 20) + (= (grind-cost p20) 45) + (= (plane-cost p20) 30) + (unused p21) + (goalsize p21 medium) + (= (spray-varnish-cost p21) 10) + (= (glaze-cost p21) 15) + (= (grind-cost p21) 30) + (= (plane-cost p21) 20) + (unused p22) + (goalsize p22 small) + (= (spray-varnish-cost p22) 5) + (= (glaze-cost p22) 10) + (= (grind-cost p22) 15) + (= (plane-cost p22) 10) + (unused p23) + (goalsize p23 large) + (= (spray-varnish-cost p23) 15) + (= (glaze-cost p23) 20) + (= (grind-cost p23) 45) + (= (plane-cost p23) 30) + (unused p24) + (goalsize p24 medium) + (= (spray-varnish-cost p24) 10) + (= (glaze-cost p24) 15) + (= (grind-cost p24) 30) + (= (plane-cost p24) 20) + (unused p25) + (goalsize p25 medium) + (= (spray-varnish-cost p25) 10) + (= (glaze-cost p25) 15) + (= (grind-cost p25) 30) + (= (plane-cost p25) 20) + (unused p26) + (goalsize p26 large) + (= (spray-varnish-cost p26) 15) + (= (glaze-cost p26) 20) + (= (grind-cost p26) 45) + (= (plane-cost p26) 30) + (unused p27) + (goalsize p27 medium) + (= (spray-varnish-cost p27) 10) + (= (glaze-cost p27) 15) + (= (grind-cost p27) 30) + (= (plane-cost p27) 20) + (unused p28) + (goalsize p28 medium) + (= (spray-varnish-cost p28) 10) + (= (glaze-cost p28) 15) + (= (grind-cost p28) 30) + (= (plane-cost p28) 20) + (unused p29) + (goalsize p29 medium) + (= (spray-varnish-cost p29) 10) + (= (glaze-cost p29) 15) + (= (grind-cost p29) 30) + (= (plane-cost p29) 20) + (boardsize b0 s5) + (wood b0 cherry) + (surface-condition b0 smooth) + (available b0) + (boardsize b1 s2) + (wood b1 mahogany) + (surface-condition b1 rough) + (available b1) + (boardsize b2 s8) + (wood b2 oak) + (surface-condition b2 rough) + (available b2) + (boardsize b3 s2) + (wood b3 oak) + (surface-condition b3 rough) + (available b3) + (boardsize b4 s7) + (wood b4 pine) + (surface-condition b4 rough) + (available b4) + (boardsize b5 s2) + (wood b5 pine) + (surface-condition b5 rough) + (available b5) + (boardsize b6 s6) + (wood b6 walnut) + (surface-condition b6 smooth) + (available b6) + (boardsize b7 s7) + (wood b7 teak) + (surface-condition b7 smooth) + (available b7) + (boardsize b8 s5) + (wood b8 teak) + (surface-condition b8 smooth) + (available b8) + (boardsize b9 s7) + (wood b9 beech) + (surface-condition b9 rough) + (available b9) + ) + (:goal + (and + (available p0) + (wood p0 pine) + (surface-condition p0 smooth) + (treatment p0 varnished) + (available p1) + (surface-condition p1 smooth) + (treatment p1 glazed) + (available p2) + (colour p2 black) + (treatment p2 glazed) + (available p3) + (colour p3 mauve) + (wood p3 oak) + (treatment p3 varnished) + (available p4) + (surface-condition p4 verysmooth) + (treatment p4 varnished) + (available p5) + (colour p5 blue) + (wood p5 teak) + (surface-condition p5 verysmooth) + (treatment p5 varnished) + (available p6) + (colour p6 white) + (treatment p6 glazed) + (available p7) + (colour p7 red) + (treatment p7 varnished) + (available p8) + (colour p8 mauve) + (surface-condition p8 verysmooth) + (treatment p8 varnished) + (available p9) + (colour p9 blue) + (wood p9 oak) + (surface-condition p9 smooth) + (available p10) + (wood p10 teak) + (surface-condition p10 verysmooth) + (available p11) + (wood p11 cherry) + (surface-condition p11 smooth) + (available p12) + (colour p12 green) + (wood p12 oak) + (treatment p12 glazed) + (available p13) + (colour p13 red) + (wood p13 beech) + (treatment p13 glazed) + (available p14) + (colour p14 green) + (treatment p14 varnished) + (available p15) + (wood p15 pine) + (surface-condition p15 smooth) + (treatment p15 varnished) + (available p16) + (colour p16 natural) + (surface-condition p16 smooth) + (available p17) + (colour p17 blue) + (surface-condition p17 verysmooth) + (available p18) + (colour p18 white) + (wood p18 oak) + (treatment p18 varnished) + (available p19) + (colour p19 blue) + (wood p19 teak) + (surface-condition p19 smooth) + (treatment p19 varnished) + (available p20) + (wood p20 walnut) + (surface-condition p20 smooth) + (available p21) + (colour p21 natural) + (wood p21 beech) + (available p22) + (colour p22 black) + (wood p22 pine) + (surface-condition p22 verysmooth) + (treatment p22 varnished) + (available p23) + (colour p23 blue) + (surface-condition p23 smooth) + (treatment p23 varnished) + (available p24) + (colour p24 red) + (surface-condition p24 verysmooth) + (available p25) + (surface-condition p25 verysmooth) + (treatment p25 varnished) + (available p26) + (colour p26 mauve) + (wood p26 teak) + (treatment p26 glazed) + (available p27) + (surface-condition p27 verysmooth) + (treatment p27 varnished) + (available p28) + (wood p28 beech) + (treatment p28 glazed) + (available p29) + (colour p29 white) + (wood p29 teak) + (surface-condition p29 verysmooth) + ) + ) + (:metric minimize (total-cost)) +) diff --git a/docs/kovacs-draft-2011.pdf b/docs/kovacs-draft-2011.pdf new file mode 100644 index 00000000..c3766780 Binary files /dev/null and b/docs/kovacs-draft-2011.pdf differ diff --git a/docs/kovacs-pddl-3.1-2011.pdf b/docs/kovacs-pddl-3.1-2011.pdf new file mode 100644 index 00000000..4779e1a4 Binary files /dev/null and b/docs/kovacs-pddl-3.1-2011.pdf differ diff --git a/docs/main.tex b/docs/main.tex new file mode 100644 index 00000000..76a74bdb --- /dev/null +++ b/docs/main.tex @@ -0,0 +1,248 @@ +\documentclass[]{article} +\usepackage[a4paper, margin=0.5in]{geometry} +\usepackage{amsmath} +\usepackage{syntax} +\usepackage[T1]{fontenc} +\setlength{\grammarparsep}{2pt plus 1pt minus 1pt} % increase separation between rules +\setlength{\grammarindent}{20em} % increase separation between LHS/RHS + +\title{Loki - Implemented PDDL Grammar Definition} +\author{Dominik Drexler} +\date{\today} + +\newcommand{\plus}{\textsuperscript{+}} +\newcommand{\typing}{\textsuperscript{:typing}~} +\newcommand{\fluents}{\textsuperscript{:fluents}~} +\newcommand{\constraints}{\textsuperscript{:constraints}~} +\newcommand{\negativepreconditions}{\textsuperscript{:negative-preconditions}~} +\newcommand{\disjunctivepreconditions}{\textsuperscript{:disjunctive-preconditions}~} +\newcommand{\existentialpreconditions}{\textsuperscript{:existential-preconditions}~} +\newcommand{\universalpreconditions}{\textsuperscript{:universal-preconditions}~} +\newcommand{\conditionaleffects}{\textsuperscript{:conditional-effects}~} + +\begin{document} +\maketitle + +\section{Domain} + +% https://tex.stackexchange.com/questions/24886/which-package-can-be-used-to-write-bnf-grammars +\begin{grammar} + ::= 0..9 + + ::= a..z | A..Z + + ::= | | - | _ + + ::= * + + ::= ? + + ::= digit\plus . digit* %% TODO int or float + + ::= | + + + ::= | ( either \plus ) | ( fluent ) + + ::= ( ) + + ::= x* + + ::= x\plus - + + + ::= + + ::= ( ) + + + + ::= + + ::= + + ::= ( ) + + ::= x* + + ::=\typing{} x\plus - + + + ::= ( t* ) + + ::= + + ::= ( not ) + + ::= | + + + ::= :strip | :typing + + ::= ( :types ) + + ::= ( :constants ) + + ::= ( :predicates * ) + + ::= ( :functions ) + + ::=\constraints ( :constraints ) + + ::= ( define ( domain )\newline + [] \newline + [] \newline + [] \newline + [] \newline + [] \newline + [*] ) + +\end{grammar} + +\section{Actions} + +\begin{grammar} + ::= ( t* ) + + ::= + + ::= ( not ) + + ::= | + + + ::= * + + ::= + + + ::= | + + ::= - + + ::= / + + ::= | | + + + ::= > + + ::= \textless + + ::= = + + ::= >= + + ::= \textgreater= + + ::= | \newline + | | \newline + | + + + ::= + + ::= ( ) + + ::= ( - ) + + ::= | ( * ) + + ::= | | | + + % Preconditions + ::= + + ::=\negativepreconditions{} + + ::= ( and * ) + + ::=\disjunctivepreconditions{} ( or * ) + + ::=\disjunctivepreconditions{} ( not * ) + + ::=\disjunctivepreconditions{} ( imply ) + + ::=\existentialpreconditions{} ( exists ) + + ::=\universalpreconditions{} ( forall ) + + ::=\fluents{} ( ) + + ::= | | | | | | | | + + ::= name + + ::= + + ::= ( and * ) + + ::= ( forall ) + + ::= ( preference ) + + ::= | | | + + + % Effects + ::= assign + + ::= scale-up + + ::= scale-down + + ::= increase + + ::= decrease + + ::= | | \newline + | | + + ::= + + ::=\fluents ( ) + + ::= | + + ::=\conditionaleffects{} ( forall ( * ) ) + + ::=\conditionaleffects{} ( when ) + + ::=\conditionaleffects{} | + + ::= | | ( and * ) +\end{grammar} + +\section{Problem} + +\begin{grammar} + ::= ( and * ) + + ::= (forall ( ) ) + + ::= ( at end ) + + ::= ( always ) + + ::= ( sometime ) + + ::= ( within ) + + ::= ( at-most-once ) + + ::= ( sometime-after ) + + ::= ( sometime-before ) + + ::= ( always-within ) + + ::= ( hold-during ) + + ::= ( hold-after ) +\end{grammar} + +\nocite{mcdermott-et-al-1998} + +\bibliographystyle{plain} +\bibliography{refs} + +\end{document} \ No newline at end of file diff --git a/docs/pddl-bnf.pdf b/docs/pddl-bnf.pdf new file mode 100644 index 00000000..d6d9c405 Binary files /dev/null and b/docs/pddl-bnf.pdf differ diff --git a/docs/refs.bib b/docs/refs.bib new file mode 100644 index 00000000..3081ad33 --- /dev/null +++ b/docs/refs.bib @@ -0,0 +1,6 @@ +@inproceedings{mcdermott-et-al-1998, + title={PDDL-the planning domain definition language}, + author={Drew McDermott and Malik Ghallab and Adele E. Howe and Craig A. Knoblock and Ashwin Ram and Manuela M. Veloso and Daniel S. Weld and David E. Wilkins}, + year={1998}, + url={https://api.semanticscholar.org/CorpusID:59656859} +} \ No newline at end of file diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 00000000..528f1a20 --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,19 @@ +add_executable(multiple_problems "multiple_problems.cpp") +target_link_libraries(multiple_problems parsers) + +add_executable(position_cache "position_cache.cpp") +target_link_libraries(position_cache parsers) + +add_executable(single_problem "single_problem.cpp") +target_link_libraries(single_problem parsers) + +add_executable(undefined_behavior "undefined_behavior.cpp") +target_link_libraries(undefined_behavior parsers) + + +add_custom_target(example_domain ALL + COMMAND ${CMAKE_COMMAND} -E copy "${PROJECT_SOURCE_DIR}/data/gripper/domain.pddl" "${CMAKE_BINARY_DIR}/data/gripper/domain.pddl") +add_custom_target(example_problem_0 ALL + COMMAND ${CMAKE_COMMAND} -E copy "${PROJECT_SOURCE_DIR}/data/gripper/p-2-0.pddl" "${CMAKE_BINARY_DIR}/data/gripper/p-2-0.pddl") +add_custom_target(example_problem_1 ALL + COMMAND ${CMAKE_COMMAND} -E copy "${PROJECT_SOURCE_DIR}/data/gripper/p-2-1.pddl" "${CMAKE_BINARY_DIR}/data/gripper/p-2-1.pddl") \ No newline at end of file diff --git a/examples/multiple_problems.cpp b/examples/multiple_problems.cpp new file mode 100644 index 00000000..3b80f272 --- /dev/null +++ b/examples/multiple_problems.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../include/loki/domain/parser.hpp" +#include "../include/loki/problem/parser.hpp" + +#include + + +int main() { + // Parse the domain + auto domain_parser = loki::DomainParser("data/gripper/domain.pddl"); + const auto domain = domain_parser.get_domain(); + std::cout << *domain << std::endl; + + // Parse first problem + const auto problem_parser = loki::ProblemParser("data/gripper/p-2-0.pddl", domain_parser); + const auto problem1 = problem_parser.get_problem(); + std::cout << *problem1 << std::endl; + + // Parse second problem where the constants are reordered + const auto problem_parser2 = loki::ProblemParser("data/gripper/p-2-1.pddl", domain_parser); + const auto problem2 = problem_parser2.get_problem(); + std::cout << *problem2 << std::endl; + + /* Both problems are structurally equivalent */ + assert(problem1 == problem2); + + /* Note: since the PDDL objects are shared over the whole class of problems, + the idexing scheme is most likely fragmented per problem. + (In this specific case, it is not fragmented because both problems are structurally equivalent) */ + + + return 0; +} diff --git a/examples/position_cache.cpp b/examples/position_cache.cpp new file mode 100644 index 00000000..aac7b1df --- /dev/null +++ b/examples/position_cache.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../include/loki/domain/parser.hpp" +#include "../include/loki/problem/parser.hpp" + +#include +#include + + +/// @brief Prints an error message when encourtering an And-Condition. +struct TestUnsupportedAndConditionVisitor { + const loki::Position position; + const loki::PDDLPositionCache& position_cache; + const loki::PDDLErrorHandler& error_handler; + + TestUnsupportedAndConditionVisitor( + const loki::Position position_, + const loki::PDDLPositionCache& position_cache_, + const loki::PDDLErrorHandler& error_handler_) + : position(position_) + , position_cache(position_cache_) + , error_handler(error_handler_) { } + + /// @brief For leaf nodes we do not need to do anything + template + void operator()(const Node&) { } + + /// @brief For inner nodes we need to recursively call the visitor + void operator()(const loki::pddl::ConditionOrImpl& node) { + for (const auto& child_node : node.get_conditions()) { + // We call front() to obtain the first occurence. + const auto child_position = position_cache.get(child_node).front(); + std::visit(TestUnsupportedAndConditionVisitor(child_position, position_cache, error_handler), *child_node); + } + } + + /// @brief For the unsupported And-Condition, + /// we print an clang-style error message and throw an exception. + void operator()(const loki::pddl::ConditionAndImpl&) { + std::cout << error_handler(position, "Your awesome error message.") << std::endl; + throw std::runtime_error("Unexpected And-Condition."); + } +}; + + +/// @brief In this example, we show how to print custom error message for unsupported PDDL types. +int main() { + // Parse the domain + auto domain_parser = loki::DomainParser("data/gripper/domain.pddl"); + const auto domain = domain_parser.get_domain(); + std::cout << *domain << std::endl << std::endl; + + const loki::PDDLPositionCache& position_cache = domain_parser.get_position_cache(); + const loki::PDDLErrorHandler& error_handler = position_cache.get_error_handler(); + + for (const auto& action : domain->get_actions()) { + const auto condition = action->get_condition(); + if (!condition.has_value()) { + continue; + } + // We call front() to obtain the first occurence. + auto condition_position = position_cache.get(condition.value()).front(); + std::visit( + TestUnsupportedAndConditionVisitor(condition_position, position_cache, error_handler), + *condition.value()); + } + + return 0; +} diff --git a/examples/single_problem.cpp b/examples/single_problem.cpp new file mode 100644 index 00000000..b2a5fd70 --- /dev/null +++ b/examples/single_problem.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../include/loki/domain/parser.hpp" +#include "../include/loki/problem/parser.hpp" + +#include + + +int main() { + // Parse the domain + auto domain_parser = loki::DomainParser("data/gripper/domain.pddl"); + const auto domain = domain_parser.get_domain(); + std::cout << *domain << std::endl; + + // Parse the problem + const auto problem_parser = loki::ProblemParser("data/gripper/p-2-0.pddl", domain_parser); + const auto problem = problem_parser.get_problem(); + std::cout << *problem << std::endl; + + return 0; +} diff --git a/examples/undefined_behavior.cpp b/examples/undefined_behavior.cpp new file mode 100644 index 00000000..bce76bba --- /dev/null +++ b/examples/undefined_behavior.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../include/loki/domain/parser.hpp" +#include "../include/loki/problem/parser.hpp" + +#include + + +/// @brief This example illustrates incorrect ownership handling +int main() { + auto domain = loki::pddl::Domain{nullptr}; + { + // Parse the domain + auto domain_parser = loki::DomainParser("data/gripper/domain.pddl"); + domain = domain_parser.get_domain(); + std::cout << *domain << std::endl; + + /* Destructor of DomainParser is called and all domain and problem specific PDDL objects are destroyed. */ + } + + std::cout << "Bye ;(" << std::endl; + + /* Undefined behavior when accessing the domain, usually the program crashes because memory was overwritten */ + std::cout << *domain << std::endl; + + return 0; +} diff --git a/exe/CMakeLists.txt b/exe/CMakeLists.txt new file mode 100644 index 00000000..14e8820b --- /dev/null +++ b/exe/CMakeLists.txt @@ -0,0 +1,6 @@ +add_executable(domain "domain.cpp") +target_link_libraries(domain parsers) + +add_executable(problem "problem.cpp") +target_link_libraries(problem parsers) + diff --git a/exe/domain.cpp b/exe/domain.cpp new file mode 100644 index 00000000..2dd013a8 --- /dev/null +++ b/exe/domain.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../include/loki/domain/parser.hpp" + +#include + + +int main(int argc, char** argv) { + if (argc < 2) { + std::cout << "Usage: interpreter " << std::endl; + return 1; + } + const auto domain_file = std::string{argv[1]}; + + // 1. Parse the domain + const auto domain_parser = loki::DomainParser(domain_file); + const auto domain = domain_parser.get_domain(); + std::cout << *domain << std::endl; + + return 0; +} + +// cmake -S . -B build -DENABLE_TESTING:bool=TRUE && cmake --build build -j16 && ./build/exe/domain benchmarks/gripper/domain.pddl && ./build/tests/domain/domain_tests \ No newline at end of file diff --git a/exe/problem.cpp b/exe/problem.cpp new file mode 100644 index 00000000..3ac2c485 --- /dev/null +++ b/exe/problem.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../include/loki/domain/parser.hpp" +#include "../include/loki/problem/parser.hpp" + +#include + + +int main(int argc, char** argv) { + if (argc < 3) { + std::cout << "Usage: interpreter " << std::endl; + return 1; + } + const auto domain_file = std::string{argv[1]}; + const auto problem_file = std::string{argv[2]}; + + // 1. Parse the domain + auto domain_parser = loki::DomainParser(domain_file); + const auto domain = domain_parser.get_domain(); + std::cout << *domain << std::endl; + + // 2. Parse the problem + const auto problem_parser = loki::ProblemParser(problem_file, domain_parser); + const auto problem = problem_parser.get_problem(); + std::cout << *problem << std::endl; + + return 0; +} + +// cmake -S . -B build -DENABLE_TESTING:bool=TRUE && cmake --build build -j16 && ./build/exe/problem benchmarks/gripper/domain.pddl benchmarks/gripper/p-2-0.pddl && ./build/tests/domain/domain_tests \ No newline at end of file diff --git a/include/loki/common/ast/config.hpp b/include/loki/common/ast/config.hpp new file mode 100644 index 00000000..c19bbd08 --- /dev/null +++ b/include/loki/common/ast/config.hpp @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_COMMON_AST_CONFIG_HPP_ +#define LOKI_INCLUDE_LOKI_COMMON_AST_CONFIG_HPP_ + +#include +#include +#include + + +/// @brief Defines types of our parsers. +/// The configuration is relevant when reusing the parsers instantiated by the library. +namespace loki +{ + namespace x3 = boost::spirit::x3; + + using Position = boost::spirit::x3::position_tagged; + using PositionList = std::vector; + + // Our iterator type + typedef std::string::const_iterator iterator_type; + + + /* X3 error handler utility */ + template + using error_handler = x3::error_handler; + + using error_handler_tag = x3::error_handler_tag; + + typedef error_handler error_handler_type; + + + /* The phrase parse context */ + typedef + x3::phrase_parse_context::type phrase_context_type; + + /* Combined error handler, pddl, and phrase parse Context */ + typedef x3::context< + error_handler_tag, + std::reference_wrapper, + phrase_context_type> + context_type; +} + +#endif diff --git a/include/loki/common/ast/error_handler.hpp b/include/loki/common/ast/error_handler.hpp new file mode 100644 index 00000000..d284619e --- /dev/null +++ b/include/loki/common/ast/error_handler.hpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_COMMON_AST_ERROR_HANDLER_HPP_ +#define LOKI_INCLUDE_LOKI_COMMON_AST_ERROR_HANDLER_HPP_ + +#include "config.hpp" + +#include +#include + + +namespace loki +{ + namespace x3 = boost::spirit::x3; + + //////////////////////////////////////////////////////////////////////////// + // Our error handler + //////////////////////////////////////////////////////////////////////////// + + struct error_handler_base + { + std::unordered_map id_map; + + error_handler_base() { } + + template + x3::error_handler_result on_error( + Iterator& /*first*/, Iterator const& /*last*/ + , Exception const& x, Context const& context) { + { + std::string which = x.which(); + auto iter = id_map.find(which); + if (iter != id_map.end()) { + which = iter->second; + } + + std::string message = "Error! Expecting: " + which + " here:"; + auto& error_handler = x3::get(context).get(); + error_handler(x.where(), message); + + return x3::error_handler_result::fail; + } + } + }; +} + +#endif diff --git a/include/loki/common/ast/error_reporting.hpp b/include/loki/common/ast/error_reporting.hpp new file mode 100644 index 00000000..7722e961 --- /dev/null +++ b/include/loki/common/ast/error_reporting.hpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_COMMON_AST_ERROR_REPORTING_HPP_ +#define LOKI_INCLUDE_LOKI_COMMON_AST_ERROR_REPORTING_HPP_ + +#include "config.hpp" + +#include + + +// Clang-style error handling utilities + +namespace loki +{ + /* Combined error handler and output stream. */ + class X3ErrorHandler { + private: + // Order of initialization matters + std::ostringstream m_error_stream; + error_handler_type m_error_handler; + + public: + X3ErrorHandler(iterator_type first, iterator_type last, const std::string& file) + : m_error_handler(error_handler_type(first, last, m_error_stream, file)) { } + + // delete copy and move to avoid dangling references. + X3ErrorHandler(const X3ErrorHandler& other) = delete; + X3ErrorHandler& operator=(const X3ErrorHandler& other) = delete; + X3ErrorHandler(X3ErrorHandler&& other) = delete; + X3ErrorHandler& operator=(X3ErrorHandler&& other) = delete; + + const error_handler_type& get_error_handler() const { + return m_error_handler; + } + + error_handler_type& get_error_handler() { + return m_error_handler; + } + + const std::ostringstream& get_error_stream() const { + return m_error_stream; + } + + std::ostringstream& get_error_stream() { + return m_error_stream; + } + }; +} + +#endif diff --git a/include/loki/common/ast/parser_wrapper.hpp b/include/loki/common/ast/parser_wrapper.hpp new file mode 100644 index 00000000..f747424c --- /dev/null +++ b/include/loki/common/ast/parser_wrapper.hpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_COMMON_AST_PARSER_WRAPPER_HPP_ +#define LOKI_INCLUDE_COMMON_AST_PARSER_WRAPPER_HPP_ + +#include "config.hpp" + +#include + + +namespace loki { + +template +bool parse_ast(Iterator& iter, Iterator end, const Parser& parser, Node& out, error_handler_type& error_handler) { + out = Node(); // reinitialize + + //assert(error_handler.get_position_cache().first() <= iter && + // end < error_handler.get_position_cache().last()); + + using boost::spirit::x3::with; + auto const wrapped_parser = + with(std::ref(error_handler)) + [ + parser + ]; + using boost::spirit::x3::ascii::space; + bool success = phrase_parse(iter, end, wrapped_parser, space, out); + return success; +} + +template +bool parse_ast(const std::string& source, const Parser& parser, Node& out, error_handler_type& error_handler) { + auto iter = source.begin(); + return parse_ast(iter, source.end(), parser, out, error_handler); +} + +template +void parse_ast(const std::string& source, const Parser& parser, Node& out) { + loki::iterator_type iter(source.begin()); + const loki::iterator_type end(source.end()); + error_handler_type error_handler(iter, end, std::cerr); + bool success = parse_ast(source, parser, out, error_handler); + if (!success) { + throw std::runtime_error("Failed parse."); + } +} + + + +} + +#endif diff --git a/include/loki/common/collections.hpp b/include/loki/common/collections.hpp new file mode 100644 index 00000000..6e1426db --- /dev/null +++ b/include/loki/common/collections.hpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_COMMON_COLLECTIONS_HPP_ +#define LOKI_INCLUDE_LOKI_COMMON_COLLECTIONS_HPP_ + +#include + +#include +#include + + +namespace loki { + +/// @brief Returns the sorted vector +/// @tparam T +/// @param vec +/// @return +template +boost::container::small_vector get_sorted_vector(const Collection& collection) { + boost::container::small_vector result(collection.begin(), collection.end()); + std::sort(result.begin(), result.end()); + return result; +} + +} + +#endif \ No newline at end of file diff --git a/include/loki/common/exceptions.hpp b/include/loki/common/exceptions.hpp new file mode 100644 index 00000000..a97b5411 --- /dev/null +++ b/include/loki/common/exceptions.hpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_COMMON_EXCEPTIONS_HPP_ +#define LOKI_INCLUDE_LOKI_COMMON_EXCEPTIONS_HPP_ + +#include + + +namespace loki { +class FileNotExistsError : public std::runtime_error { +public: + explicit FileNotExistsError(const std::string& path_to_file); +}; + + +class SyntaxParserError : public std::runtime_error { +public: + explicit SyntaxParserError(const std::string& message, const std::string& error_handler_output); +}; + + +class SemanticParserError : public std::runtime_error { +public: + explicit SemanticParserError(const std::string& message, const std::string& error_handler_output); +}; + + +class NotImplementedError : public std::runtime_error { +public: + explicit NotImplementedError(const std::string& message); +}; + + +} + +#endif \ No newline at end of file diff --git a/include/loki/common/filesystem.hpp b/include/loki/common/filesystem.hpp new file mode 100644 index 00000000..cb2726b0 --- /dev/null +++ b/include/loki/common/filesystem.hpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_COMMON_FILESYSTEM_HPP_ +#define LOKI_INCLUDE_LOKI_COMMON_FILESYSTEM_HPP_ + + +// Older versions of LibC++ does not have filesystem (e.g., ubuntu 18.04), use the experimental version +// https://stackoverflow.com/questions/55474690/stdfilesystem-has-not-been-declared-after-including-experimental-filesystem +#ifndef __has_include + static_assert(false, "__has_include not supported"); +#else +# if __cplusplus >= 201703L && __has_include() +# include + namespace fs = std::filesystem; +# elif __has_include() +# include + namespace fs = std::experimental::filesystem; +# elif __has_include() +# include + namespace fs = boost::filesystem; +# endif +#endif + + +namespace loki +{ + +extern std::string read_file(const fs::path& file_path); + +} + +#endif \ No newline at end of file diff --git a/include/loki/common/hash.hpp b/include/loki/common/hash.hpp new file mode 100644 index 00000000..4c13061b --- /dev/null +++ b/include/loki/common/hash.hpp @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_COMMON_HASH_HPP_ +#define LOKI_INCLUDE_LOKI_COMMON_HASH_HPP_ + +#include +#include +#include +#include + + +namespace loki { + +// -------------- +// Hash functions +// -------------- + +template +inline void hash_combine(size_t& seed, const T& val) +{ + seed ^= std::hash()(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2); +} + +template<> +inline void hash_combine(size_t& seed, const std::size_t& val) +{ + seed ^= val + 0x9e3779b9 + (seed << 6) + (seed >> 2); +} + +template +inline size_t hash_combine(const Types&... args) +{ + size_t seed = 0; + (hash_combine(seed, args), ...); + return seed; +} + +template +inline std::size_t hash_container(const Container& container) +{ + using T = typename Container::value_type; + const auto hash_function = std::hash(); + std::size_t aggregated_hash = 0; + for (const auto& item : container) + { + const auto item_hash = hash_function(item); + hash_combine(aggregated_hash, item_hash); + } + return aggregated_hash; +} + +template +struct hash_container_type { + size_t operator()(const Container& container) const { + return hash_container(container); + } +}; + +} + + +#endif \ No newline at end of file diff --git a/include/loki/common/memory.hpp b/include/loki/common/memory.hpp new file mode 100644 index 00000000..a28926c1 --- /dev/null +++ b/include/loki/common/memory.hpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +// Taken from: https://stackoverflow.com/questions/669438/how-to-get-memory-usage-at-runtime-using-c + +#include +#include +#include +#include +#include +#include + +////////////////////////////////////////////////////////////////////////////// +// +// Read the system-dependent data for a process' virtual memory +// size and resident set size, and return the results in KB. +// +// On failure, returns 0.0, 0.0 +namespace loki { + +extern std::tuple process_mem_usage(); + +} \ No newline at end of file diff --git a/include/loki/common/pddl/base.hpp b/include/loki/common/pddl/base.hpp new file mode 100644 index 00000000..592fc07c --- /dev/null +++ b/include/loki/common/pddl/base.hpp @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_COMMON_PDDL_BASE_HPP_ +#define LOKI_INCLUDE_LOKI_COMMON_PDDL_BASE_HPP_ + +#include "../printer.hpp" + +#include +#include +#include + + +namespace loki { +/// @brief Implements a common base class for PDDL objects. +/// +/// Each PDDL object has an identifier. +/// Identifiers are used to describe and detect semantically equivalent PDDL object. +/// Detecting semantic equivalence is important for +/// - reducing the required memory by detecting duplicates +/// - reducing comparison and hashing to pointer level instead of traversing the whole structure +/// For the following type of PDDL objects, loki detects semantic equivalence: +/// * Type +/// * Object +/// * Variable +/// * Term +/// * Atom +/// * NumericFluent +/// * Literal +/// * Parameter +/// * Function +/// * FunctionSkeleton +/// * Requirements +/// For the remaining type of PDDL objects, loki approximates semantic equivalence +/// with structural equivalence where collections of objects are sorted by the identifier. +/// For example, loki detects semantic equivalence of a conjunction of atoms +/// but loki does not detect semantic equivalence of an arbitrary formula of atoms. +template +class Base { +protected: + int m_identifier; + +public: + explicit Base(int identifier) : m_identifier(identifier) { } + + // moveable but not copyable + Base(const Base& other) = delete; + Base& operator=(const Base& other) = delete; + Base(Base&& other) = default; + Base& operator=(Base&& other) = default; + + constexpr const auto& self() const { return static_cast(*this); } + + bool operator==(const Base& other) const { + return self().is_structurally_equivalent_to_impl(other.self()); + } + + bool operator!=(const Base& other) const { + return !(*this == other); + } + + bool operator<(const Base& other) const { + return m_identifier < other.m_identifier; + } + + bool operator>(const Base& other) const { + return m_identifier > other.m_identifier; + } + + size_t hash() const { + return self().hash_impl(); + } + + /// @brief Overload of the output stream insertion operator (operator<<). + friend std::ostream& operator<<(std::ostream& os, const Base& element) { + os << element.str(); + return os; + } + + /// @brief Compute a string representation of this object. + void str(std::ostringstream& out, const FormattingOptions& options) const { + self().str_impl(out, options); + } + + /// @brief Compute a string representation of this object. + std::string str() const { + std::ostringstream out; + FormattingOptions options{0, 4}; + str(out, options); + return out.str(); + } + + /// @brief Returns the identifier + int get_identifier() const { + return m_identifier; + } +}; + +} + +#endif \ No newline at end of file diff --git a/include/loki/common/pddl/config.hpp b/include/loki/common/pddl/config.hpp new file mode 100644 index 00000000..b177b906 --- /dev/null +++ b/include/loki/common/pddl/config.hpp @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_COMMON_PDDL_CONFIG_HPP_ +#define LOKI_INCLUDE_LOKI_COMMON_PDDL_CONFIG_HPP_ + +#include "error_reporting.hpp" + +#include "../ast/config.hpp" + + +namespace loki +{ + typedef PDDLErrorHandlerImpl PDDLErrorHandler; +} + +#endif diff --git a/include/loki/common/pddl/context.hpp b/include/loki/common/pddl/context.hpp new file mode 100644 index 00000000..3074c8cb --- /dev/null +++ b/include/loki/common/pddl/context.hpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_COMMON_PDDL_CONTEXT_HPP_ +#define LOKI_INCLUDE_LOKI_COMMON_PDDL_CONTEXT_HPP_ + +#include "position.hpp" +#include "reference.hpp" +#include "scope.hpp" +#include "types.hpp" + +namespace loki +{ + + struct Context + { + // For the unique construction of PDDL objects + CompositeOfPDDLFactories& factories; + // For storing the positions in the input PDDL file + PDDLPositionCache& positions; + // For referencing to existing bindings + ScopeStack& scopes; + // For checking that certain PDDL objects were referenced at least once + ReferencedPDDLObjects references; + // For convenience, to avoid an additional parameter during semantic parsing + pddl::Requirements requirements; + + Context(CompositeOfPDDLFactories &factories_, PDDLPositionCache& positions_, ScopeStack &scopes_) + : factories(factories_), positions(positions_), scopes(scopes_), references(ReferencedPDDLObjects()), requirements(nullptr) {} + }; + +} + +#endif \ No newline at end of file diff --git a/include/loki/common/pddl/declarations.hpp b/include/loki/common/pddl/declarations.hpp new file mode 100644 index 00000000..edb23b95 --- /dev/null +++ b/include/loki/common/pddl/declarations.hpp @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_COMMON_PDDL_DECLARATIONS_HPP_ +#define LOKI_INCLUDE_LOKI_COMMON_PDDL_DECLARATIONS_HPP_ + +#include + + +namespace loki { + template + using PDDLElement = const T*; + + using ElementsPerSegment = size_t; +} + +#endif diff --git a/include/loki/common/pddl/error_reporting.hpp b/include/loki/common/pddl/error_reporting.hpp new file mode 100644 index 00000000..1bb774dc --- /dev/null +++ b/include/loki/common/pddl/error_reporting.hpp @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_COMMON_PDDL_ERROR_REPORTING_HPP_ +#define LOKI_INCLUDE_LOKI_COMMON_PDDL_ERROR_REPORTING_HPP_ + +#include "../filesystem.hpp" + +#include + +#include +#include + + +// Clang-style error handling utilities + +// It is a modified version of the boost error_handler: https://github.com/boostorg/spirit +// It is basically a const version of the boost error_handler accepting +// a position cache that contains the positions in the input stream. +// Furthermore, instead of writing errors to an ostream, we return string directly to make this thread-safe. + +namespace loki +{ + using position_tagged = boost::spirit::x3::position_tagged; + + template + class PDDLErrorHandlerImpl + { + public: + + typedef Iterator iterator_type; + using position_cache = boost::spirit::x3::position_cache>; + + PDDLErrorHandlerImpl(position_cache pos_cache, fs::path file = "", int tabs = 4) + : pos_cache(pos_cache) + , file(file) + , tabs(tabs) {} + + std::string operator()(Iterator err_pos, std::string const& error_message) const; + std::string operator()(Iterator err_first, Iterator err_last, std::string const& error_message) const; + std::string operator()(position_tagged pos, std::string const& message) const + { + auto where = pos_cache.position_of(pos); + return (*this)(where.begin(), where.end(), message); + } + + boost::iterator_range position_of(position_tagged pos) const + { + return pos_cache.position_of(pos); + } + + private: + + std::string print_file_line(std::size_t line) const; + std::string print_line(Iterator line_start, Iterator last) const; + std::string print_indicator(Iterator& line_start, Iterator last, char ind) const; + Iterator get_line_start(Iterator first, Iterator pos) const; + std::size_t position(Iterator i) const; + + position_cache pos_cache; + std::string file; + int tabs; + }; + + template + std::string PDDLErrorHandlerImpl::print_file_line(std::size_t line) const + { + std::ostringstream err_out; + if (file != "") + { + err_out << "In file " << file << ", "; + } + else + { + err_out << "In "; + } + + err_out << "line " << line << ':' << std::endl; + return err_out.str(); + } + + template + std::string PDDLErrorHandlerImpl::print_line(Iterator start, Iterator last) const + { + std::ostringstream err_out; + auto end = start; + while (end != last) + { + auto c = *end; + if (c == '\r' || c == '\n') + break; + else + ++end; + } + typedef typename std::iterator_traits::value_type char_type; + std::basic_string line{start, end}; + err_out << boost::spirit::x3::to_utf8(line) << std::endl; + return err_out.str(); + } + + template + std::string PDDLErrorHandlerImpl::print_indicator(Iterator& start, Iterator last, char ind) const + { + std::ostringstream err_out; + for (; start != last; ++start) + { + auto c = *start; + if (c == '\r' || c == '\n') + break; + else if (c == '\t') + for (int i = 0; i < tabs; ++i) + err_out << ind; + else + err_out << ind; + } + return err_out.str(); + } + + template + inline Iterator PDDLErrorHandlerImpl::get_line_start(Iterator first, Iterator pos) const + { + Iterator latest = first; + for (Iterator i = first; i != pos;) + if (*i == '\r' || *i == '\n') + latest = ++i; + else + ++i; + return latest; + } + + template + std::size_t PDDLErrorHandlerImpl::position(Iterator i) const + { + std::size_t line { 1 }; + typename std::iterator_traits::value_type prev { 0 }; + + for (Iterator pos = pos_cache.first(); pos != i; ++pos) { + auto c = *pos; + switch (c) { + case '\n': + if (prev != '\r') ++line; + break; + case '\r': + ++line; + break; + default: + break; + } + prev = c; + } + + return line; + } + + template + std::string PDDLErrorHandlerImpl::operator()( + Iterator err_pos, std::string const& error_message) const + { + Iterator first = pos_cache.first(); + Iterator last = pos_cache.last(); + + std::ostringstream err_out; + err_out << print_file_line(position(err_pos)); + err_out << error_message << std::endl; + + Iterator start = get_line_start(first, err_pos); + err_out << print_line(start, last); + err_out << print_indicator(start, err_pos, '_'); + err_out << "^_" << std::endl; + return err_out.str(); + } + + template + std::string PDDLErrorHandlerImpl::operator()( + Iterator err_first, Iterator err_last, std::string const& error_message) const + { + Iterator first = pos_cache.first(); + Iterator last = pos_cache.last(); + + std::ostringstream err_out; + err_out << print_file_line(position(err_first)); + err_out << error_message << std::endl; + + Iterator start = get_line_start(first, err_first); + err_out << print_line(start, last); + err_out << print_indicator(start, err_first, ' '); + err_out << print_indicator(start, err_last, '~'); + err_out << " <<-- Here" << std::endl; + return err_out.str(); + } + +} + +#endif diff --git a/include/loki/common/pddl/garbage_collected_factory.hpp b/include/loki/common/pddl/garbage_collected_factory.hpp new file mode 100644 index 00000000..5aca59ed --- /dev/null +++ b/include/loki/common/pddl/garbage_collected_factory.hpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_COMMON_PDDL_GARBAGE_COLLECTED_FACTORY_HPP_ +#define LOKI_INCLUDE_LOKI_COMMON_PDDL_GARBAGE_COLLECTED_FACTORY_HPP_ + +#include +#include +#include +#include +#include +#include + + +namespace loki { + +/* Not used anymore but still a useful piece of code. */ + +/// @brief A thread-safe reference-counted object cache. +/// An idea by Herb Sutter. +/// Custom deleter idea: https://stackoverflow.com/questions/49782011/herb-sutters-10-liner-with-cleanup +/// TODO: improve the quality of the answer on stackoverflow +template +class GarbageCollectedFactory { +private: + + /// @brief Encapsulates the data of a single type. + template + struct PerTypeCache { + std::unordered_set uniqueness; + std::unordered_map> identifier_to_object; + }; + + /// @brief Encapsulates the data of all types. + struct Cache { + std::tuple...> data; + // Identifiers are shared across types since types can be polymorphic + int count = 0; + // Mutex is shared for thread-safe changes to count that is shared across types + std::mutex mutex; + }; + + std::shared_ptr m_cache; + +public: + GarbageCollectedFactory() + : m_cache(std::make_shared()) { } + + /// @brief Gets a shared reference to the object of type T with the given arguments. + /// If such an object does not exists then it creates one. + /// @tparam ...Args The arguments that are passed to the constructor of T. + /// @param ...args + /// @return + template + [[nodiscard]] std::shared_ptr get_or_create(Args... args) { + /* we must declare sp before locking the mutex + s.t. the deleter is called after the mutex was released in case of stack unwinding. */ + std::shared_ptr sp; + std::lock_guard hold(m_cache->mutex); + + auto& t_cache = std::get>(m_cache->data); + int identifier = m_cache->count; + auto key = T(identifier, args...); + const auto& [it, inserted] = t_cache.uniqueness.insert(key); + if (!inserted) { + assert(t_cache.identifier_to_object.count(it->get_identifier())); + return t_cache.identifier_to_object.at(it->get_identifier()).lock(); + } + ++m_cache->count; + /* Must explicitly call the constructor of T to give exclusive access to the factory. */ + // Extensions: To ensure that the memory for T and the control block is allocated once, + // we could use std::allocated_shared and provide a custom allocator. + sp = std::shared_ptr( + new T(identifier, args...), + [cache=m_cache, identifier](T* x) + { + { + std::lock_guard hold(cache->mutex); + auto& t_cache = std::get>(cache->data); + t_cache.uniqueness.erase(*x); + t_cache.identifier_to_object.erase(identifier); + } + /* After cache removal, we can call the objects destructor + and recursively call the deleter of children if their ref count goes to 0 */ + delete x; + } + ); + t_cache.identifier_to_object.emplace(identifier, sp); + return sp; + } + + template + size_t size() const { + std::lock_guard hold(m_cache->mutex); + auto& t_cache = std::get>(m_cache->data); + return t_cache.uniqueness.size(); + } +}; + +} + +#endif \ No newline at end of file diff --git a/include/loki/common/pddl/persistent_factory.hpp b/include/loki/common/pddl/persistent_factory.hpp new file mode 100644 index 00000000..23c532f0 --- /dev/null +++ b/include/loki/common/pddl/persistent_factory.hpp @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_COMMON_PDDL_PERSISTENT_FACTORY_HPP_ +#define LOKI_INCLUDE_LOKI_COMMON_PDDL_PERSISTENT_FACTORY_HPP_ + +#include "declarations.hpp" +#include "segmented_vector.hpp" + +#include +#include +#include +#include +#include +#include + + +namespace loki { +/// @brief The PersistentFactory class manages unique objects in a persistent +/// and efficient manner, utilizing a combination of unordered_set for +/// uniqueness checks and SegmentedVector for continuous and +/// cache-efficient storage. +/// @tparam HolderType is the nested type which can be an std::variant. +/// @tparam N is the number of elements per segment +template +class PersistentFactory { +private: + template + struct DerferencedHash { + std::size_t operator()(const T* ptr) const { + return std::hash()(*ptr); + } + }; + + /// @brief Equality comparison of the objects underlying the pointers. + template + struct DereferencedEquality { + bool operator()(const T* left, const T* right) const { + return *left == *right; + } + }; + + // We use an unordered_set to test for uniqueness. + // We use pointers to the persistent memory to reduce allocations. + std::unordered_set, DereferencedEquality> m_uniqueness_set; + // Use pre-allocated memory to store PDDL object persistent and continuously for improved cache locality. + SegmentedVector m_persistent_vector; + + int m_count = 0; + + std::mutex m_mutex; + +public: + /// @brief Returns a pointer to an existing object + /// or creates it before if it does not exist.v + template + [[nodiscard]] HolderType const* get_or_create(Args... args) { + std::lock_guard hold(m_mutex); + /* Construct and insert the element in persistent memory. */ + int identifier = m_count; + // Ensure that element with identifier i is stored at position i. + assert((identifier == (static_cast(m_persistent_vector.size())-1)) + || (identifier == static_cast(m_persistent_vector.size()))); + // The pointer to the location in persistent memory. + const auto* element_ptr = static_cast(nullptr); + // Explicitly call the constructor of T to give exclusive access to the factory. + auto element = HolderType(std::move(SubType(identifier, std::move(args)...))); + bool overwrite_last_element = (identifier == static_cast(m_persistent_vector.size()) - 1); + if (overwrite_last_element) { + element_ptr = &(m_persistent_vector[identifier] = std::move(element)); + } else { + element_ptr = &(m_persistent_vector.push_back(std::move(element))); + } + /* Test for uniqueness */ + auto it = m_uniqueness_set.find(element_ptr); + if (it == m_uniqueness_set.end()) { + // Element is unique! + m_uniqueness_set.emplace(element_ptr); + // Validate the element by increasing the identifier to the next free position + ++m_count; + } else { + // Element is not unique! + // Return the existing one. + element_ptr = *it; + } + return element_ptr; + } + + size_t size() const { + return m_count; + } +}; + +} + + +#endif \ No newline at end of file diff --git a/include/loki/common/pddl/position.hpp b/include/loki/common/pddl/position.hpp new file mode 100644 index 00000000..9086b291 --- /dev/null +++ b/include/loki/common/pddl/position.hpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_COMMON_PDDL_POSITION_HPP_ +#define LOKI_INCLUDE_LOKI_COMMON_PDDL_POSITION_HPP_ + +#include "config.hpp" +#include "declarations.hpp" + +#include "../ast/error_reporting.hpp" +#include "../filesystem.hpp" + +#include + + +namespace loki { +template +using PositionMapType = std::unordered_map, PositionList>; + +/// @brief Stores all occurrences of a PDDL object in the input file for each PDDL type T. +template +class PositionCache { + private: + std::tuple...> m_positions; + + PDDLErrorHandler m_error_handler; + + public: + PositionCache(const X3ErrorHandler& error_handler, const fs::path& file, int tabs=4); + + template + void push_back(const PDDLElement& element, const Position& position); + + template + PositionList get(const PDDLElement& element) const; + + const PDDLErrorHandler& get_error_handler() const; +}; + +} + +#include "position.tpp" + +#endif \ No newline at end of file diff --git a/include/loki/common/pddl/position.tpp b/include/loki/common/pddl/position.tpp new file mode 100644 index 00000000..4a825295 --- /dev/null +++ b/include/loki/common/pddl/position.tpp @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +namespace loki { + +template +PositionCache::PositionCache(const X3ErrorHandler& error_handler, const fs::path& file, int tabs) + : m_error_handler(PDDLErrorHandler(error_handler.get_error_handler().get_position_cache(), file, tabs)) { } + + +template +template +void PositionCache::push_back(const PDDLElement& element, const Position& position) { + auto& t_positions = std::get>(m_positions); + t_positions[element].push_back(position); +} + +template +template +PositionList PositionCache::get(const PDDLElement& element) const { + auto& t_positions = std::get>(m_positions); + auto it = t_positions.find(element); + if (it != t_positions.end()) { + return it->second; + } + return {}; +} + +template +const PDDLErrorHandler& PositionCache::get_error_handler() const { + return m_error_handler; +} + +} diff --git a/include/loki/common/pddl/reference.hpp b/include/loki/common/pddl/reference.hpp new file mode 100644 index 00000000..6fa2a38a --- /dev/null +++ b/include/loki/common/pddl/reference.hpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_COMMON_PDDL_REFERENCE_HPP_ +#define LOKI_INCLUDE_LOKI_COMMON_PDDL_REFERENCE_HPP_ + +#include "../../common/ast/config.hpp" +#include "../../domain/pddl/object.hpp" +#include "../../domain/pddl/predicate.hpp" +#include "../../domain/pddl/requirements.hpp" +#include "../../domain/pddl/function_skeleton.hpp" +#include "../../domain/pddl/variable.hpp" + +#include + +#include +#include +#include +#include +#include +#include + + +namespace loki { +/// @brief Encapsulates tracking of references of PDDL objects. +/// +/// Example usage: +/// 1. Track all variables of the parameters of an action. +/// 2. Parse the conditions and effects while untracking +/// variables that are referenced. +/// 3. Verify that all variables are untracked, meaning +/// that they were referenced at least once. +template +class References { + private: + std::tuple...> references; + + public: + /// @brief Returns a pointer if it exists. + template + bool exists(T reference) const; + + /// @brief Inserts a pointer of type T + template + void track(T reference); + + /// @brief Erases a pointer of Type T + template + void untrack(T reference); +}; + +using ReferencedPDDLObjects = References; + +} + +#include "reference.tpp" + +#endif diff --git a/include/loki/common/pddl/reference.tpp b/include/loki/common/pddl/reference.tpp new file mode 100644 index 00000000..cc8df305 --- /dev/null +++ b/include/loki/common/pddl/reference.tpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + + +namespace loki { + +template +template +bool References::exists(T reference) const { + const auto& t_references = std::get>(references); + return t_references.count(reference); +} + + +template +template +void References::track(T reference) { + auto& t_references = std::get>(references); + t_references.insert(reference); +} + + +template +template +void References::untrack(T reference) { + auto& t_references = std::get>(references); + t_references.erase(reference); +} + +} diff --git a/include/loki/common/pddl/scope.hpp b/include/loki/common/pddl/scope.hpp new file mode 100644 index 00000000..34204d17 --- /dev/null +++ b/include/loki/common/pddl/scope.hpp @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_COMMON_PDDL_SCOPE_HPP_ +#define LOKI_INCLUDE_LOKI_COMMON_PDDL_SCOPE_HPP_ + +#include "config.hpp" +#include "declarations.hpp" + +#include "../../common/ast/config.hpp" +#include "../../domain/pddl/type.hpp" +#include "../../domain/pddl/object.hpp" +#include "../../domain/pddl/predicate.hpp" +#include "../../domain/pddl/function_skeleton.hpp" +#include "../../domain/pddl/variable.hpp" + +#include + +#include +#include +#include +#include +#include +#include + + +namespace loki { + +/// @brief Encapsulates binding related information of a type T. +/// The object is the entity bound to the name. +/// The position points to the matched location +/// in the input stream and is used for error reporting. +template +using BindingValueType = std::tuple, std::optional>; + +/// @brief Datastructure to store bindings of a type T. +template +using BindingMapType = std::unordered_map>; + + +/// @brief Encapsulates bindings for different types. +template +class Bindings { + private: + std::tuple...> bindings; + + public: + /// @brief Returns a binding if it exists. + template + std::optional> get(const std::string& key) const; + + /// @brief Inserts a binding of type T + template + void insert( + const std::string& key, + const PDDLElement& binding, + const std::optional& position); +}; + + +/// @brief Wraps bindings in a scope with reference to a parent scope. +class Scope { + private: + const Scope* m_parent_scope; + + Bindings bindings; + + public: + explicit Scope(const Scope* parent_scope = nullptr); + + // delete copy and move to avoid dangling references. + Scope(const Scope& other) = delete; + Scope& operator=(const Scope& other) = delete; + Scope(Scope&& other) = delete; + Scope& operator=(Scope&& other) = delete; + + /// @brief Returns a binding if it exists. + template + std::optional> get(const std::string& name) const; + + /// @brief Insert a binding of type T. + template + void insert(const std::string& name, const PDDLElement& element, const std::optional& position); +}; + + +/// @brief Encapsulates the result of search for a binding with the corresponding ErrorHandler. +template +using ScopeStackSearchResult = std::tuple, const std::optional, const PDDLErrorHandler&>; + + +/// @brief Implements a scoping mechanism to store bindings which are mappings from name to a pointer to a PDDL object +/// type and a position in the input stream that can be used to construct error messages with the given ErrorHandler. +/// +/// We use ScopeStacks indicated with surrounding "[.]" to stack scopes indicated with surrounding "(.)" to store bindings. +/// We initialize the parsing step by creating a ScopeStack with a single scope that we call the global scope. +/// During parsing we can open and close new scopes but we must ensure that only the single global scope remains. +/// We can access bindings by calling the get method and the matching binding in the nearest scope is returned. +/// We can also insert new bindings in the current scope. +/// +/// During domain file parsing, we have a single scope stack structured as follows: +/// [ (Domain Scope Global), (Domain Scope Child 1), (Domain Scope Child 2), ... ] +/// +/// During problem file parsing, we get access to bindings from the domain through additional composition as follows: +/// [ (Domain Scope Global) ], [ (Problem Scope Global), (Problem Scope Child 1), (Problem Scope Child 2), ... ] +class ScopeStack { + private: + std::deque> m_stack; + + const PDDLErrorHandler& m_error_handler; + + const ScopeStack* m_parent; + + public: + ScopeStack(const PDDLErrorHandler& error_handler, + const ScopeStack* parent=nullptr); + + // delete copy and move to avoid dangling references. + ScopeStack(const ScopeStack& other) = delete; + ScopeStack& operator=(const ScopeStack& other) = delete; + ScopeStack(ScopeStack&& other) = delete; + ScopeStack& operator=(ScopeStack&& other) = delete; + + /// @brief Inserts a new scope on the top of the stack. + void open_scope(); + + /// @brief Deletes the topmost scope from the stack. + void close_scope(); + + /// @brief Returns a binding if it exists. + template + std::optional> get(const std::string& name) const; + + /// @brief Insert a binding of type T. + template + void insert(const std::string& name, const PDDLElement& element, const std::optional& position); + + /// @brief Get the error handler to print an error message. + const PDDLErrorHandler& get_error_handler() const; + + // For testing purposes only. + const std::deque>& get_stack() const; +}; + + +} + +#include "scope.tpp" + +#endif diff --git a/include/loki/common/pddl/scope.tpp b/include/loki/common/pddl/scope.tpp new file mode 100644 index 00000000..51b69ec5 --- /dev/null +++ b/include/loki/common/pddl/scope.tpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +namespace loki { + +template +template +std::optional> Bindings::get(const std::string& key) const { + const auto& t_bindings = std::get>(bindings); + auto it = t_bindings.find(key); + if (it != t_bindings.end()) { + return {it->second}; + } + return std::nullopt; +} + + +template +template +void Bindings::insert(const std::string& key, const PDDLElement& element, const std::optional& position) { + assert(element); + auto& t_bindings = std::get>(bindings); + assert(!t_bindings.count(key)); + t_bindings.emplace(key, std::make_tuple(element, position)); +} + + +template +std::optional> Scope::get(const std::string& name) const { + const auto result = bindings.get(name); + if (result.has_value()) return result.value(); + if (m_parent_scope) { + return m_parent_scope->get(name); + } + return std::nullopt; +} + + +template +void Scope::insert(const std::string& name, const PDDLElement& element, const std::optional& position) { + assert(element); + assert(!this->get(name)); + bindings.insert(name, element, position); +} + + +template +std::optional> ScopeStack::get(const std::string& name) const { + assert(!m_stack.empty()); + auto result = m_stack.back()->get(name); + if (result.has_value()) { + return std::make_tuple( + std::get<0>(result.value()), + std::get<1>(result.value()), + std::cref(m_error_handler)); + } + if (m_parent) return m_parent->get(name); + return std::nullopt; +} + +/// @brief Insert a binding of type T. +template +void ScopeStack::insert(const std::string& name, const PDDLElement& element, const std::optional& position) { + assert(!m_stack.empty()); + m_stack.back()->insert(name, element, position); +} + + +} \ No newline at end of file diff --git a/include/loki/common/pddl/segmented_vector.hpp b/include/loki/common/pddl/segmented_vector.hpp new file mode 100644 index 00000000..35b81a71 --- /dev/null +++ b/include/loki/common/pddl/segmented_vector.hpp @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_COMMON_PDDL_SEGMENTED_VECTOR_HPP_ +#define LOKI_INCLUDE_LOKI_COMMON_PDDL_SEGMENTED_VECTOR_HPP_ + +#include "declarations.hpp" + +#include +#include +#include +#include +#include +#include + + +namespace loki { +/// @brief The SegmentedVector persistently stores elements of type T +/// in segments of size N, ensuring that references to elements do not +/// become invalidated upon reallocation. +/// @tparam T is the nested type +/// @tparam N is the number of elements per segment +template +class SegmentedVector { +private: + std::vector> m_data; + + size_t m_size; + size_t m_capacity; + + void increase_capacity() { + // Add an additional vector with capacity N + m_data.resize(m_data.size() + 1); + m_data.back().reserve(N); + // Increase total capacity + m_capacity += N; + } + + size_t segment_index(int identifier) const { + return identifier / N; + } + + size_t element_index(int identifier) const { + return identifier % N; + } + +public: + explicit SegmentedVector() : m_size(0), m_capacity(0) { } + + const T& push_back(T value) { + // Increase capacity if necessary + if (m_size >= m_capacity) { + increase_capacity(); + } + auto& segment = m_data[segment_index(size())]; + + // Take ownership of memory + segment.push_back(std::move(value)); + // Fetch return value + const T& return_value = segment[element_index(size())]; + + ++m_size; + return return_value; + } + + T& operator[](int index) { + assert(index < static_cast(size())); + return m_data[segment_index(index)][element_index(index)]; + } + + const T& operator[](int identifier) const { + assert(identifier >= 0 && identifier <= static_cast(size())); + return m_data[segment_index(identifier)][element_index(identifier)]; + } + + size_t size() const { + return m_size; + } + + size_t capacity() const { + return m_capacity; + } +}; + +} + +#endif \ No newline at end of file diff --git a/include/loki/common/pddl/types.hpp b/include/loki/common/pddl/types.hpp new file mode 100644 index 00000000..afbc52b8 --- /dev/null +++ b/include/loki/common/pddl/types.hpp @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_COMMON_PDDL_TYPES_HPP_ +#define LOKI_INCLUDE_LOKI_COMMON_PDDL_TYPES_HPP_ + +#include "position.hpp" +#include "persistent_factory.hpp" + +#include "../../domain/pddl/action.hpp" +#include "../../domain/pddl/atom.hpp" +#include "../../domain/pddl/conditions.hpp" +#include "../../domain/pddl/derived_predicate.hpp" +#include "../../domain/pddl/domain.hpp" +#include "../../domain/pddl/effects.hpp" +#include "../../domain/pddl/function_expressions.hpp" +#include "../../domain/pddl/function_skeleton.hpp" +#include "../../domain/pddl/function.hpp" +#include "../../domain/pddl/literal.hpp" +#include "../../domain/pddl/object.hpp" +#include "../../domain/pddl/parameter.hpp" +#include "../../domain/pddl/predicate.hpp" +#include "../../domain/pddl/requirements.hpp" +#include "../../domain/pddl/term.hpp" +#include "../../domain/pddl/type.hpp" +#include "../../domain/pddl/variable.hpp" +#include "../../problem/pddl/problem.hpp" +#include "../../problem/pddl/metric.hpp" +#include "../../problem/pddl/numeric_fluent.hpp" + + +namespace loki { +// The segmented sizes are chosen sufficiently large to avoid +// to avoid allocations and for continuous storage. +// The values are just educated guesses based on the knowledge +// that cache line size is 64 Bytes. +using RequirementFactory = PersistentFactory; +using TypeFactory = PersistentFactory; +using VariableFactory = PersistentFactory; +using TermFactory = PersistentFactory; +using ObjectFactory = PersistentFactory; +using AtomFactory = PersistentFactory; +using LiteralFactory = PersistentFactory; +using ParameterFactory = PersistentFactory; +using PredicateFactory = PersistentFactory; +using FunctionExpressionFactory = PersistentFactory; +using FunctionFactory = PersistentFactory; +using FunctionSkeletonFactory = PersistentFactory; +using ConditionFactory = PersistentFactory; +using EffectFactory = PersistentFactory; +using ActionFactory = PersistentFactory; +using DerivedPredicateFactory = PersistentFactory; +using OptimizationMetricFactory = PersistentFactory; +using NumericFluentFactory = PersistentFactory; +using DomainFactory = PersistentFactory; +using ProblemFactory = PersistentFactory; + + +using PDDLPositionCache = PositionCache; + + +/// @brief Collection of factories for the unique creation of PDDL objects. +struct CollectionOfPDDLFactories { + RequirementFactory requirements; + TypeFactory types; + VariableFactory variables; + TermFactory terms; + ObjectFactory objects; + AtomFactory domain_atoms; + AtomFactory problem_atoms; // ground atoms + LiteralFactory domain_literals; + LiteralFactory problem_literals; // ground literals + ParameterFactory parameters; + PredicateFactory predicates; + FunctionExpressionFactory function_expressions; + FunctionFactory functions; + FunctionSkeletonFactory function_skeletons; + ConditionFactory conditions; + EffectFactory effects; + ActionFactory actions; + DerivedPredicateFactory derived_predicates; + OptimizationMetricFactory optimization_metrics; + NumericFluentFactory numeric_fluents; + DomainFactory domains; + ProblemFactory problems; + + CollectionOfPDDLFactories() = default; + + // delete copy and move to avoid dangling references. + CollectionOfPDDLFactories(const CollectionOfPDDLFactories& other) = delete; + CollectionOfPDDLFactories& operator=(const CollectionOfPDDLFactories& other) = delete; + CollectionOfPDDLFactories(CollectionOfPDDLFactories&& other) = delete; + CollectionOfPDDLFactories& operator=(CollectionOfPDDLFactories&& other) = delete; +}; + +/// @brief Composition of factories used for parsing the domain. +/// Allows to obtain problem specific indexing schemes +/// by using problem specific factories. +/// We currently use problem specific factories for atoms and literals +struct CompositeOfPDDLFactories { + RequirementFactory& requirements; + TypeFactory& types; + VariableFactory& variables; + TermFactory& terms; + ObjectFactory& objects; + AtomFactory& atoms; + LiteralFactory& literals; + ParameterFactory& parameters; + PredicateFactory& predicates; + FunctionExpressionFactory& function_expressions; + FunctionFactory& functions; + FunctionSkeletonFactory& function_skeletons; + ConditionFactory& conditions; + EffectFactory& effects; + ActionFactory& actions; + DerivedPredicateFactory& derived_predicates; + OptimizationMetricFactory& optimization_metrics; + NumericFluentFactory& numeric_fluents; + DomainFactory& domains; + ProblemFactory& problems; +}; + +} + +#endif \ No newline at end of file diff --git a/include/loki/common/pddl/visitors.hpp b/include/loki/common/pddl/visitors.hpp new file mode 100644 index 00000000..a67177ed --- /dev/null +++ b/include/loki/common/pddl/visitors.hpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_COMMON_PDDL_VISITORS_HPP_ +#define LOKI_INCLUDE_LOKI_COMMON_PDDL_VISITORS_HPP_ + +#include "../printer.hpp" + +#include + + +namespace loki::pddl { +struct LessComparatorVisitor { + template + bool operator()(const T1& object_left, const T2& object_right) const { + return object_left.get_identifier() < object_right.get_identifier(); + } +}; + +struct StringifyVisitor { + std::ostringstream& out; + const FormattingOptions& options; + + StringifyVisitor(std::ostringstream& out_, const FormattingOptions& options_) + : out(out_), options(options_) { } + + template + void operator()(const T& object) { + object.str(out, options); + } +}; + +} + + + +#endif diff --git a/include/loki/common/printer.hpp b/include/loki/common/printer.hpp new file mode 100644 index 00000000..0e072b87 --- /dev/null +++ b/include/loki/common/printer.hpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_COMMON_PRINTER_HPP_ +#define LOKI_INCLUDE_LOKI_COMMON_PRINTER_HPP_ + + +namespace loki { + +struct FormattingOptions { + // The indentation in the current level. + int indent = 0; + // The amount of indentation added per nesting + int add_indent = 0; +}; + +} + +#endif \ No newline at end of file diff --git a/include/loki/domain/ast/ast.hpp b/include/loki/domain/ast/ast.hpp new file mode 100644 index 00000000..c98fb5d3 --- /dev/null +++ b/include/loki/domain/ast/ast.hpp @@ -0,0 +1,942 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_AST_AST_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_AST_AST_HPP_ + +#include +#include +#include + +#include +#include +#include + + +namespace loki::domain::ast +{ + /////////////////////////////////////////////////////////////////////////// + // The AST + /////////////////////////////////////////////////////////////////////////// + namespace x3 = boost::spirit::x3; + + struct Name; + struct Variable; + struct FunctionSymbol; + struct Term; + struct Number; + struct Predicate; + + struct RequirementStrips; + struct RequirementTyping; + struct RequirementNegativePreconditions; + struct RequirementDisjunctivePreconditions; + struct RequirementEquality; + struct RequirementExistentialPreconditions; + struct RequirementUniversalPreconditions; + struct RequirementQuantifiedPreconditions; + struct RequirementConditionalEffects; + struct RequirementFluents; // PDDL 3.1 = :object-fluents + :numeric-fluents + struct RequirementObjectFluents; // PDDL 3.1 + struct RequirementNumericFluents; // PDDL 3.1 + struct RequirementAdl; + struct RequirementDurativeActions; + struct RequirementDerivedPredicates; + struct RequirementTimedInitialLiterals; + struct RequirementPreferences; + struct RequirementConstraints; + struct RequirementActionCosts; + struct Requirement; + + struct Type; + struct TypeObject; + struct TypeNumber; + struct TypeEither; + struct TypedListOfNamesRecursively; // :typing + struct TypedListOfNames; + struct TypedListOfVariablesRecursively; // :typing + struct TypedListOfVariables; + + struct AtomicFormulaSkeleton; + + struct AtomicFunctionSkeletonTotalCost; + struct AtomicFunctionSkeletonGeneral; + struct AtomicFunctionSkeleton; + struct FunctionTypedListOfAtomicFunctionSkeletonsRecursively; + struct FunctionTypedListOfAtomicFunctionSkeletons; + + struct AtomicFormulaOfTermsPredicate; + struct AtomicFormulaOfTermsEquality; // :equality + struct AtomicFormulaOfTerms; + struct Atom; + struct NegatedAtom; + struct Literal; + + struct MultiOperatorMul; + struct MultiOperatorPlus; + struct MultiOperator; + struct BinaryOperatorMinus; + struct BinaryOperatorDiv; + struct BinaryOperator; + + struct BinaryComparatorGreater; + struct BinaryComparatorLess; + struct BinaryComparatorEqual; + struct BinaryComparatorGreaterEqual; + struct BinaryComparatorLessEqual; + struct BinaryComparator; + + struct FunctionHead; + struct FunctionExpression; // :numeric-fluents + struct FunctionExpressionNumber; + struct FunctionExpressionBinaryOp; + struct FunctionExpressionMinus; + struct FunctionExpressionHead; + + struct GoalDescriptor; + struct GoalDescriptorAtom; + struct GoalDescriptorLiteral; // :negative-preconditions + struct GoalDescriptorAnd; + struct GoalDescriptorOr; // :disjunctive-preconditions + struct GoalDescriptorNot; // :disjunctive-preconditions + struct GoalDescriptorImply; // :disjunctive-preconditions + struct GoalDescriptorExists; // :existential-preconditions + struct GoalDescriptorForall; // :universal-preconditions + struct GoalDescriptorFunctionComparison; // :numeric-fluents + + struct ConstraintGoalDescriptor; + struct ConstraintGoalDescriptorAnd; + struct ConstraintGoalDescriptorForall; + struct ConstraintGoalDescriptorAtEnd; + struct ConstraintGoalDescriptorAlways; + struct ConstraintGoalDescriptorSometime; + struct ConstraintGoalDescriptorWithin; + struct ConstraintGoalDescriptorAtMostOnce; + struct ConstraintGoalDescriptorSometimeAfter; + struct ConstraintGoalDescriptorSometimeBefore; + struct ConstraintGoalDescriptorAlwaysWithin; + struct ConstraintGoalDescriptorHoldDuring; + struct ConstraintGoalDescriptorHoldAfter; + + struct PreferenceName; + struct PreconditionGoalDescriptor; + struct PreconditionGoalDescriptorSimple; + struct PreconditionGoalDescriptorAnd; + struct PreconditionGoalDescriptorPreference; // :preferences + struct PreconditionGoalDescriptorForall; // :universal-preconditions + + struct AssignOperatorAssign; + struct AssignOperatorScaleUp; + struct AssignOperatorScaleDown; + struct AssignOperatorIncrease; + struct AssignOperatorDecrease; + struct AssignOperator; + + struct Effect; + struct EffectProductionLiteral; + struct EffectProductionNumericFluentTotalCost; + struct EffectProductionNumericFluentGeneral; + struct EffectProduction; + struct EffectConditionalForall; + struct EffectConditionalWhen; + struct EffectConditional; + + struct ActionSymbol; + struct ActionBody; + + struct Action; + struct DerivedPredicate; // :derived-predicates + + struct DomainName; + struct Requirements; + struct Types; // : typing + struct Constants; + struct Predicates; + struct Functions; + struct Constraints; // :constraints + struct Structure; + struct Domain; + + + /* */ + struct Name : x3::position_tagged + { + std::string characters; + }; + + /* */ + struct Variable : x3::position_tagged + { + std::string characters; + }; + + /* */ + struct FunctionSymbol : x3::position_tagged + { + Name name; + }; + + /* */ + struct Term : x3::position_tagged, + x3::variant< + Name, + Variable> + { + using base_type::base_type; + using base_type::operator=; + }; + + /* */ + struct Number : x3::position_tagged + { + double value; + }; + + /* */ + struct Predicate : x3::position_tagged + { + Name name; + }; + + /* */ + struct RequirementStrips : x3::position_tagged + { + }; + + struct RequirementTyping : x3::position_tagged + { + }; + + struct RequirementNegativePreconditions : x3::position_tagged + { + }; + + struct RequirementDisjunctivePreconditions : x3::position_tagged + { + }; + + struct RequirementEquality : x3::position_tagged + { + }; + + struct RequirementExistentialPreconditions : x3::position_tagged + { + }; + + struct RequirementUniversalPreconditions : x3::position_tagged + { + }; + + struct RequirementQuantifiedPreconditions : x3::position_tagged + { + }; + + struct RequirementConditionalEffects : x3::position_tagged + { + }; + + struct RequirementFluents : x3::position_tagged + { + }; + + struct RequirementObjectFluents : x3::position_tagged + { + }; + + struct RequirementNumericFluents : x3::position_tagged + { + }; + + struct RequirementAdl : x3::position_tagged + { + }; + + struct RequirementDurativeActions : x3::position_tagged + { + }; + + struct RequirementDerivedPredicates : x3::position_tagged + { + }; + + struct RequirementTimedInitialLiterals : x3::position_tagged + { + }; + + struct RequirementPreferences : x3::position_tagged + { + }; + + struct RequirementConstraints : x3::position_tagged + { + }; + + struct RequirementActionCosts : x3::position_tagged + { + }; + + struct Requirement : x3::position_tagged, + x3::variant< + RequirementStrips, + RequirementTyping, + RequirementNegativePreconditions, + RequirementDisjunctivePreconditions, + RequirementEquality, + RequirementExistentialPreconditions, + RequirementUniversalPreconditions, + RequirementQuantifiedPreconditions, + RequirementConditionalEffects, + RequirementFluents, + RequirementObjectFluents, + RequirementNumericFluents, + RequirementAdl, + RequirementDurativeActions, + RequirementDerivedPredicates, + RequirementTimedInitialLiterals, + RequirementPreferences, + RequirementConstraints, + RequirementActionCosts> + { + using base_type::base_type; + using base_type::operator=; + }; + + struct Requirements : x3::position_tagged + { + std::vector requirements; + }; + + /* */ + struct Type : x3::position_tagged, + x3::variant< + Name, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast> + { + using base_type::base_type; + using base_type::operator=; + }; + + struct TypeObject : x3::position_tagged { }; + + struct TypeNumber : x3::position_tagged { }; + + struct TypeEither : x3::position_tagged + { + std::vector types; + }; + + struct TypedListOfNamesRecursively : x3::position_tagged + { + std::vector names; + Type type; + x3::forward_ast typed_list_of_names; + }; + + struct TypedListOfNames : x3::position_tagged, + x3::variant< + std::vector, // base type is object + TypedListOfNamesRecursively> + { + using base_type::base_type; + using base_type::operator=; + }; + + /* */ + struct TypedListOfVariablesRecursively : x3::position_tagged + { + std::vector variables; + Type type; + x3::forward_ast typed_list_of_variables; + }; + + struct TypedListOfVariables : x3::position_tagged, + x3::variant< + std::vector, + TypedListOfVariablesRecursively> + { + using base_type::base_type; + using base_type::operator=; + }; + + /* */ + struct AtomicFormulaSkeleton : x3::position_tagged + { + Predicate predicate; + TypedListOfVariables typed_list_of_variables; + }; + + /* */ + struct AtomicFunctionSkeletonTotalCost : x3::position_tagged { + FunctionSymbol function_symbol; + }; + + struct AtomicFunctionSkeletonGeneral : x3::position_tagged { + FunctionSymbol function_symbol; + TypedListOfVariables arguments; + }; + + struct AtomicFunctionSkeleton : x3::position_tagged, + x3::variant< + AtomicFunctionSkeletonTotalCost, + AtomicFunctionSkeletonGeneral> { + using base_type::base_type; + using base_type::operator=; + }; + + struct FunctionTypedListOfAtomicFunctionSkeletonsRecursively : x3::position_tagged + { + std::vector atomic_function_skeletons; + TypeNumber function_type; + boost::optional> function_typed_list_of_atomic_function_skeletons; + }; + + struct FunctionTypedListOfAtomicFunctionSkeletons : x3::position_tagged, + x3::variant< + std::vector, // :numeric-fluents and deprecated (https://ipc08.icaps-conference.org/deterministic/PddlExtension.html) + FunctionTypedListOfAtomicFunctionSkeletonsRecursively> + { + using base_type::base_type; + using base_type::operator=; + }; + + /* Atomic formulas */ + struct AtomicFormulaOfTermsPredicate : x3::position_tagged + { + Predicate predicate; + std::vector terms; + }; + + struct AtomicFormulaOfTermsEquality : x3::position_tagged + { + Term term_left; + Term term_right; + }; + + struct AtomicFormulaOfTerms : x3::position_tagged, + x3::variant< + AtomicFormulaOfTermsPredicate, + AtomicFormulaOfTermsEquality> + { + using base_type::base_type; + using base_type::operator=; + }; + + struct Atom : x3::position_tagged + { + AtomicFormulaOfTerms atomic_formula_of_terms; + }; + + struct NegatedAtom : x3::position_tagged + { + AtomicFormulaOfTerms atomic_formula_of_terms; + }; + + struct Literal : x3::position_tagged, + x3::variant< + Atom, + NegatedAtom> + { + using base_type::base_type; + using base_type::operator=; + }; + + /* Operators */ + struct MultiOperatorMul : x3::position_tagged + { + }; + + struct MultiOperatorPlus : x3::position_tagged + { + }; + + struct MultiOperator : x3::position_tagged, + x3::variant< + MultiOperatorMul, + MultiOperatorPlus> + { + using base_type::base_type; + using base_type::operator=; + }; + + struct BinaryOperatorMinus : x3::position_tagged + { + }; + + struct BinaryOperatorDiv : x3::position_tagged + { + }; + + struct BinaryOperator : x3::position_tagged, + x3::variant< + BinaryOperatorMinus, + BinaryOperatorDiv, + MultiOperator> + { + using base_type::base_type; + using base_type::operator=; + }; + + struct BinaryComparatorGreater : x3::position_tagged + { + }; + + struct BinaryComparatorLess : x3::position_tagged + { + }; + + struct BinaryComparatorEqual : x3::position_tagged + { + }; + + struct BinaryComparatorGreaterEqual : x3::position_tagged + { + }; + + struct BinaryComparatorLessEqual : x3::position_tagged + { + }; + + struct BinaryComparator : x3::position_tagged, + x3::variant< + BinaryComparatorGreater, + BinaryComparatorLess, + BinaryComparatorEqual, + BinaryComparatorGreaterEqual, + BinaryComparatorLessEqual> + { + using base_type::base_type; + using base_type::operator=; + }; + + struct FunctionHead : x3::position_tagged + { + FunctionSymbol function_symbol; + std::vector terms; + }; + + struct FunctionExpression : x3::position_tagged, + x3::variant< + x3::forward_ast, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast> + { + using base_type::base_type; + using base_type::operator=; + }; + + struct FunctionExpressionNumber : x3::position_tagged + { + Number number; + }; + + struct FunctionExpressionBinaryOp : x3::position_tagged + { + BinaryOperator binary_operator; + FunctionExpression function_expression_left; + FunctionExpression function_expression_right; + }; + + struct FunctionExpressionMinus : x3::position_tagged + { + FunctionExpression function_expression; + }; + + struct FunctionExpressionHead : x3::position_tagged + { + FunctionHead function_head; + }; + + /* Goal Descriptors */ + struct GoalDescriptor : x3::position_tagged, + x3::variant< + x3::forward_ast, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast> + { + using base_type::base_type; + using base_type::operator=; + }; + + struct GoalDescriptorAtom : x3::position_tagged + { + Atom atom; + }; + + struct GoalDescriptorLiteral : x3::position_tagged + { + Literal literal; + }; + + struct GoalDescriptorAnd : x3::position_tagged + { + std::vector goal_descriptors; + }; + + struct GoalDescriptorOr : x3::position_tagged + { + std::vector goal_descriptors; + }; + + struct GoalDescriptorNot : x3::position_tagged + { + GoalDescriptor goal_descriptor; + }; + + struct GoalDescriptorImply : x3::position_tagged + { + GoalDescriptor goal_descriptor_left; + GoalDescriptor goal_descriptor_right; + }; + + struct GoalDescriptorExists : x3::position_tagged + { + TypedListOfVariables typed_list_of_variables; + GoalDescriptor goal_descriptor; + }; + + struct GoalDescriptorForall : x3::position_tagged + { + TypedListOfVariables typed_list_of_variables; + GoalDescriptor goal_descriptor; + }; + + struct GoalDescriptorFunctionComparison : x3::position_tagged + { + BinaryComparator binary_comparator; + FunctionExpression function_expression_left; + FunctionExpression function_expression_right; + }; + + /* */ + struct ConstraintGoalDescriptor : x3::position_tagged, + x3::variant< + x3::forward_ast, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast> + { + using base_type::base_type; + using base_type::operator=; + }; + + struct ConstraintGoalDescriptorAnd : x3::position_tagged + { + std::vector constraint_goal_descriptors; + }; + + struct ConstraintGoalDescriptorForall : x3::position_tagged + { + TypedListOfVariables typed_list_of_variables; + ConstraintGoalDescriptor constraint_goal_descriptor; + }; + + struct ConstraintGoalDescriptorAtEnd : x3::position_tagged + { + GoalDescriptor goal_descriptor; + }; + + struct ConstraintGoalDescriptorAlways : x3::position_tagged + { + GoalDescriptor goal_descriptor; + }; + + struct ConstraintGoalDescriptorSometime : x3::position_tagged + { + GoalDescriptor goal_descriptor; + }; + + struct ConstraintGoalDescriptorWithin : x3::position_tagged + { + Number number; + GoalDescriptor goal_descriptor; + }; + + struct ConstraintGoalDescriptorAtMostOnce : x3::position_tagged + { + GoalDescriptor goal_descriptor; + }; + + struct ConstraintGoalDescriptorSometimeAfter : x3::position_tagged + { + GoalDescriptor goal_descriptor_left; + GoalDescriptor goal_descriptor_right; + }; + + struct ConstraintGoalDescriptorSometimeBefore : x3::position_tagged + { + GoalDescriptor goal_descriptor_left; + GoalDescriptor goal_descriptor_right; + }; + + struct ConstraintGoalDescriptorAlwaysWithin : x3::position_tagged + { + Number number; + GoalDescriptor goal_descriptor_left; + GoalDescriptor goal_descriptor_right; + }; + + struct ConstraintGoalDescriptorHoldDuring : x3::position_tagged + { + Number number_left; + Number number_right; + GoalDescriptor goal_descriptor; + }; + + struct ConstraintGoalDescriptorHoldAfter : x3::position_tagged + { + Number number; + GoalDescriptor goal_descriptor; + }; + + /* */ + struct PreferenceName : x3::position_tagged + { + Name name; + }; + + struct PreconditionGoalDescriptor : x3::position_tagged, + x3::variant< + x3::forward_ast, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast> + { + using base_type::base_type; + using base_type::operator=; + }; + + struct PreconditionGoalDescriptorSimple : x3::position_tagged + { + GoalDescriptor goal_descriptor; + }; + + struct PreconditionGoalDescriptorAnd : x3::position_tagged + { + std::vector precondition_goal_descriptors; + }; + + struct PreconditionGoalDescriptorPreference : x3::position_tagged + { + PreferenceName preference_name; + GoalDescriptor goal_descriptor; + }; + + struct PreconditionGoalDescriptorForall : x3::position_tagged + { + TypedListOfVariables typed_list_of_variables; + PreconditionGoalDescriptor precondition_goal_descriptor; + }; + + /* */ + struct AssignOperatorAssign : x3::position_tagged + { + }; + + struct AssignOperatorScaleUp : x3::position_tagged + { + }; + + struct AssignOperatorScaleDown : x3::position_tagged + { + }; + + struct AssignOperatorIncrease : x3::position_tagged + { + }; + + struct AssignOperatorDecrease : x3::position_tagged + { + }; + + struct AssignOperator : x3::position_tagged, + x3::variant< + AssignOperatorAssign, + AssignOperatorScaleUp, + AssignOperatorScaleDown, + AssignOperatorIncrease, + AssignOperatorDecrease> + { + using base_type::base_type; + using base_type::operator=; + }; + + + /* */ + // + struct Effect : x3::position_tagged, + x3::variant< + x3::forward_ast, + x3::forward_ast, + std::vector> + { + using base_type::base_type; + using base_type::operator=; + }; + + struct EffectProductionLiteral : x3::position_tagged + { + Literal literal; + }; + + struct EffectProductionNumericFluentTotalCost : x3::position_tagged + { + AssignOperatorIncrease assign_operator_increase; + FunctionSymbol function_symbol_total_cost; + FunctionExpression numeric_term; + }; + + struct EffectProductionNumericFluentGeneral : x3::position_tagged + { + AssignOperator assign_operator; + FunctionHead function_head; + FunctionExpression function_expression; + }; + + struct EffectProduction : x3::position_tagged, + x3::variant< + EffectProductionLiteral, + EffectProductionNumericFluentTotalCost, + EffectProductionNumericFluentGeneral> + { + using base_type::base_type; + using base_type::operator=; + }; + + struct EffectConditionalForall : x3::position_tagged + { + TypedListOfVariables typed_list_of_variables; + Effect effect; + }; + + struct EffectConditionalWhen : x3::position_tagged + { + GoalDescriptor goal_descriptor; + Effect effect; + }; + + struct EffectConditional : x3::position_tagged, + x3::variant< + EffectConditionalForall, + EffectConditionalWhen> + { + using base_type::base_type; + using base_type::operator=; + }; + + /* */ + struct ActionSymbol : x3::position_tagged + { + Name name; + }; + + struct ActionBody : x3::position_tagged + { + boost::optional precondition_goal_descriptor; + boost::optional effect; + }; + + struct Action : x3::position_tagged + { + ActionSymbol action_symbol; + TypedListOfVariables typed_list_of_variables; + ActionBody action_body; + }; + + + /* */ + struct DerivedPredicate : x3::position_tagged { + TypedListOfVariables typed_list_of_variables; + GoalDescriptor goal_descriptor; + }; + + /* */ + struct Types : x3::position_tagged + { + TypedListOfNames typed_list_of_names; + }; + + /* */ + struct Constants : x3::position_tagged + { + TypedListOfNames typed_list_of_names; + }; + + /* */ + struct Predicates : x3::position_tagged + { + std::vector atomic_formula_skeletons; + }; + + /* */ + struct Functions : x3::position_tagged + { + FunctionTypedListOfAtomicFunctionSkeletons function_types_list_of_atomic_function_skeletons; + }; + + /* */ + struct Constraints : x3::position_tagged + { + ConstraintGoalDescriptor constraint_goal_descriptor; + }; + + /* */ + struct Structure : x3::position_tagged, + x3::variant< + Action, + DerivedPredicate> + { + using base_type::base_type; + using base_type::operator=; + }; + + /* */ + struct DomainName : x3::position_tagged + { + Name name; + }; + + struct Domain : x3::position_tagged + { + DomainName domain_name; + boost::optional requirements; + boost::optional types; + boost::optional constants; + boost::optional predicates; + boost::optional functions; + boost::optional constraints; + std::vector structures; + }; +} + +#endif \ No newline at end of file diff --git a/include/loki/domain/ast/error_handler.hpp b/include/loki/domain/ast/error_handler.hpp new file mode 100644 index 00000000..c31d8d02 --- /dev/null +++ b/include/loki/domain/ast/error_handler.hpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_AST_ERROR_HANDLER_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_AST_ERROR_HANDLER_HPP_ + +#include "../../common/ast/error_handler.hpp" + +#include +#include + + +namespace loki::domain +{ + namespace x3 = boost::spirit::x3; + + struct error_handler_domain : error_handler_base { + error_handler_domain() : error_handler_base() { + id_map["name"] = "Name"; + } + }; +} + +#endif diff --git a/include/loki/domain/ast/parser.hpp b/include/loki/domain/ast/parser.hpp new file mode 100644 index 00000000..6e326d49 --- /dev/null +++ b/include/loki/domain/ast/parser.hpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_SYNTACTIC_PARSER_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_SYNTACTIC_PARSER_HPP_ + +#include "ast.hpp" + +#include + + +namespace loki::domain +{ + namespace x3 = boost::spirit::x3; + + /////////////////////////////////////////////////////////////////////////// + // parser public interface + /////////////////////////////////////////////////////////////////////////// + namespace parser { + struct DomainClass; + + typedef x3::rule domain_type; + + BOOST_SPIRIT_DECLARE(domain_type) + } + + parser::domain_type const& domain(); +} + +#endif \ No newline at end of file diff --git a/include/loki/domain/ast/printer.hpp b/include/loki/domain/ast/printer.hpp new file mode 100644 index 00000000..ecdec6f0 --- /dev/null +++ b/include/loki/domain/ast/printer.hpp @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_AST_PRINTER_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_AST_PRINTER_HPP_ + +#include "ast.hpp" +#include "../../common/printer.hpp" + + +namespace loki { + +// create string representations from ast nodes. +extern std::string parse_text(const domain::ast::Name& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::Variable& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::Number& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::FunctionSymbol& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::Term& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::Predicate& node, const FormattingOptions& options={}); + +extern std::string parse_text(const domain::ast::RequirementStrips& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::RequirementTyping& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::RequirementNegativePreconditions& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::RequirementDisjunctivePreconditions& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::RequirementEquality& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::RequirementExistentialPreconditions& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::RequirementUniversalPreconditions& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::RequirementQuantifiedPreconditions& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::RequirementConditionalEffects& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::RequirementFluents& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::RequirementObjectFluents& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::RequirementNumericFluents& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::RequirementAdl& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::RequirementDurativeActions& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::RequirementDerivedPredicates& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::RequirementTimedInitialLiterals& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::RequirementPreferences& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::RequirementConstraints& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::RequirementActionCosts& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::Requirement& node, const FormattingOptions& options={}); + +extern std::string parse_text(const domain::ast::Type& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::TypeObject& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::TypeNumber& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::TypeEither& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::TypedListOfNamesRecursively& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::TypedListOfNames& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::TypedListOfVariablesRecursively& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::TypedListOfVariables& node, const FormattingOptions& options={}); + +extern std::string parse_text(const domain::ast::AtomicFormulaSkeleton& node, const FormattingOptions& options={}); + +extern std::string parse_text(const domain::ast::AtomicFunctionSkeletonTotalCost& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::AtomicFunctionSkeletonGeneral& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::AtomicFunctionSkeleton& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::FunctionTypedListOfAtomicFunctionSkeletonsRecursively& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::FunctionTypedListOfAtomicFunctionSkeletons& node, const FormattingOptions& options={}); + +extern std::string parse_text(const domain::ast::AtomicFormulaOfTermsPredicate& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::AtomicFormulaOfTermsEquality& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::AtomicFormulaOfTerms& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::Atom& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::NegatedAtom& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::Literal& node, const FormattingOptions& options={}); + +extern std::string parse_text(const domain::ast::MultiOperatorMul& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::MultiOperatorPlus& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::MultiOperator& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::BinaryOperatorMinus& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::BinaryOperatorDiv& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::BinaryOperator& node, const FormattingOptions& options={}); + +extern std::string parse_text(const domain::ast::BinaryComparatorGreater& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::BinaryComparatorLess& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::BinaryComparatorEqual& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::BinaryComparatorGreaterEqual& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::BinaryComparatorLessEqual& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::BinaryComparator& node, const FormattingOptions& options={}); + +extern std::string parse_text(const domain::ast::FunctionHead& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::FunctionExpression& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::FunctionExpressionNumber& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::FunctionExpressionBinaryOp& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::FunctionExpressionMinus& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::FunctionExpressionHead& node, const FormattingOptions& options={}); + +extern std::string parse_text(const domain::ast::GoalDescriptor& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::GoalDescriptorAtom& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::GoalDescriptorLiteral& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::GoalDescriptorAnd& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::GoalDescriptorOr& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::GoalDescriptorNot& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::GoalDescriptorImply& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::GoalDescriptorExists& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::GoalDescriptorForall& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::GoalDescriptorFunctionComparison& node, const FormattingOptions& options={}); + +extern std::string parse_text(const domain::ast::ConstraintGoalDescriptor& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::ConstraintGoalDescriptorAnd& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::ConstraintGoalDescriptorForall& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::ConstraintGoalDescriptorAtEnd& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::ConstraintGoalDescriptorAlways& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::ConstraintGoalDescriptorSometime& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::ConstraintGoalDescriptorWithin& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::ConstraintGoalDescriptorAtMostOnce& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::ConstraintGoalDescriptorSometimeAfter& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::ConstraintGoalDescriptorSometimeBefore& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::ConstraintGoalDescriptorAlwaysWithin& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::ConstraintGoalDescriptorHoldDuring& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::ConstraintGoalDescriptorHoldAfter& node, const FormattingOptions& options={}); + +extern std::string parse_text(const domain::ast::PreferenceName& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::PreconditionGoalDescriptor& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::PreconditionGoalDescriptorSimple& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::PreconditionGoalDescriptorAnd& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::PreconditionGoalDescriptorPreference& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::PreconditionGoalDescriptorForall& node, const FormattingOptions& options={}); + +extern std::string parse_text(const domain::ast::AssignOperatorAssign& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::AssignOperatorScaleUp& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::AssignOperatorScaleDown& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::AssignOperatorIncrease& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::AssignOperatorDecrease& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::AssignOperator& node, const FormattingOptions& options={}); + +extern std::string parse_text(const domain::ast::Effect& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::EffectProductionLiteral& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::EffectProductionNumericFluentTotalCost& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::EffectProductionNumericFluentGeneral& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::EffectProduction& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::EffectConditionalForall& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::EffectConditionalWhen& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::EffectConditional& node, const FormattingOptions& options={}); + +extern std::string parse_text(const domain::ast::ActionSymbol& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::ActionBody& node, const FormattingOptions& options={}); + +extern std::string parse_text(const domain::ast::Action& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::DerivedPredicate& node, const FormattingOptions& options={}); + +extern std::string parse_text(const domain::ast::DomainName& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::Requirements& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::Types& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::Constants& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::Predicates& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::Functions& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::Constraints& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::Structure& node, const FormattingOptions& options={}); +extern std::string parse_text(const domain::ast::Domain& node, const FormattingOptions& options={}); + +} + +#endif \ No newline at end of file diff --git a/include/loki/domain/parser.hpp b/include/loki/domain/parser.hpp new file mode 100644 index 00000000..39b6b72c --- /dev/null +++ b/include/loki/domain/parser.hpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_PARSER_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_PARSER_HPP_ + +#include "pddl/declarations.hpp" + +#include "../common/pddl/context.hpp" +#include "../common/filesystem.hpp" + + +namespace loki { + +class DomainParser { +private: + fs::path m_file_path; + // We need to keep the source in memory for error reporting. + std::string m_source; + + CollectionOfPDDLFactories m_factories; + + // The matched positions in the input PDDL file. + std::unique_ptr m_position_cache; + + std::unique_ptr m_scopes; + + // Parsed result + pddl::Domain m_domain; + + friend class ProblemParser; + +public: + explicit DomainParser(const fs::path& file_path); + + /// @brief Get factories to create additional PDDL objects. + CollectionOfPDDLFactories& get_factories(); + + /// @brief Get position caches to be able to reference back to the input PDDL file. + const PDDLPositionCache& get_position_cache() const; + + /// @brief Get the parsed domain. + const pddl::Domain& get_domain() const; +}; + +} + +#endif \ No newline at end of file diff --git a/include/loki/domain/pddl/action.hpp b/include/loki/domain/pddl/action.hpp new file mode 100644 index 00000000..5237e20f --- /dev/null +++ b/include/loki/domain/pddl/action.hpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_PDDL_ACTION_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_PDDL_ACTION_HPP_ + +#include "declarations.hpp" +#include "conditions.hpp" +#include "effects.hpp" + +#include "../../common/pddl/base.hpp" + +#include +#include +#include + + +namespace loki { +template +class PersistentFactory; +} + + +namespace loki::pddl { +class ActionImpl : public Base { +private: + std::string m_name; + ParameterList m_parameters; + std::optional m_condition; + std::optional m_effect; + + ActionImpl(int identifier, std::string name, ParameterList parameters, std::optional condition, std::optional effect); + + template + friend class loki::PersistentFactory; + +public: + /// @brief Test for structural equivalence + bool is_structurally_equivalent_to_impl(const ActionImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const std::string& get_name() const; + const ParameterList& get_parameters() const; + const std::optional& get_condition() const; + const std::optional& get_effect() const; +}; + +} + + +namespace std { + // Inject comparison and hash function to make pointers behave appropriately with ordered and unordered datastructures + template<> + struct less + { + bool operator()(const loki::pddl::Action& left_action, const loki::pddl::Action& right_action) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::ActionImpl& action) const; + }; +} + + +#endif diff --git a/include/loki/domain/pddl/atom.hpp b/include/loki/domain/pddl/atom.hpp new file mode 100644 index 00000000..5f885cb9 --- /dev/null +++ b/include/loki/domain/pddl/atom.hpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_PDDL_ATOM_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_PDDL_ATOM_HPP_ + +#include "declarations.hpp" + +#include "../../common/pddl/base.hpp" + + +namespace loki { +template +class PersistentFactory; +} + + +namespace loki::pddl { +class AtomImpl : public Base { +private: + Predicate m_predicate; + TermList m_terms; + + template + friend class loki::PersistentFactory; + +public: + AtomImpl(int identifier, Predicate predicate, TermList terms); + + /// @brief Test for semantic equivalence + bool is_structurally_equivalent_to_impl(const AtomImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const Predicate& get_predicate() const; + const TermList& get_terms() const; +}; + +} + + +namespace std { + // Inject comparison and hash function to make pointers behave appropriately with ordered and unordered datastructures + template<> + struct less + { + bool operator()(const loki::pddl::Atom& left_atom, const loki::pddl::Atom& right_atom) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::AtomImpl& atom) const; + }; +} + +#endif diff --git a/include/loki/domain/pddl/conditions.hpp b/include/loki/domain/pddl/conditions.hpp new file mode 100644 index 00000000..0738cd96 --- /dev/null +++ b/include/loki/domain/pddl/conditions.hpp @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_PDDL_CONDITIONS_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_PDDL_CONDITIONS_HPP_ + +#include "declarations.hpp" + +#include "../../common/pddl/base.hpp" + +#include +#include + + +namespace loki { +template +class PersistentFactory; +} + + +namespace loki::pddl { + +/* Literal */ +class ConditionLiteralImpl : public Base { +private: + Literal m_literal; + + ConditionLiteralImpl(int identifier, Literal literal); + + template + friend class loki::PersistentFactory; + +public: + bool is_structurally_equivalent_to_impl(const ConditionLiteralImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const Literal& get_literal() const; +}; + + +/* And */ +class ConditionAndImpl : public Base { +private: + ConditionList m_conditions; + + ConditionAndImpl(int identifier, ConditionList conditions); + + template + friend class loki::PersistentFactory; + +public: + bool is_structurally_equivalent_to_impl(const ConditionAndImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const ConditionList& get_conditions() const; +}; + + +/* Or */ +class ConditionOrImpl : public Base { +private: + ConditionList m_conditions; + + ConditionOrImpl(int identifier, ConditionList conditions); + + template + friend class loki::PersistentFactory; + +public: + bool is_structurally_equivalent_to_impl(const ConditionOrImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const ConditionList& get_conditions() const; +}; + + +/* Not */ +class ConditionNotImpl : public Base { +private: + Condition m_condition; + + ConditionNotImpl(int identifier, Condition condition); + + template + friend class loki::PersistentFactory; + +public: + bool is_structurally_equivalent_to_impl(const ConditionNotImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const Condition& get_condition() const; +}; + + +/* Imply */ +class ConditionImplyImpl : public Base { +private: + Condition m_condition_left; + Condition m_condition_right; + + ConditionImplyImpl(int identifier, Condition condition_left, Condition condition_right); + + template + friend class loki::PersistentFactory; + +public: + bool is_structurally_equivalent_to_impl(const ConditionImplyImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const Condition& get_condition_left() const; + const Condition& get_condition_right() const; +}; + + +/* Exists */ +class ConditionExistsImpl : public Base { +private: + ParameterList m_parameters; + Condition m_condition; + + ConditionExistsImpl(int identifier, ParameterList parameters, Condition condition); + + template + friend class loki::PersistentFactory; + +public: + bool is_structurally_equivalent_to_impl(const ConditionExistsImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const ParameterList& get_parameters() const; + const Condition& get_condition() const; +}; + + +/* Forall */ +class ConditionForallImpl : public Base { +private: + ParameterList m_parameters; + Condition m_condition; + + ConditionForallImpl(int identifier, ParameterList parameters, Condition condition); + + template + friend class loki::PersistentFactory; + +public: + bool is_structurally_equivalent_to_impl(const ConditionForallImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const ParameterList& get_parameters() const; + const Condition& get_condition() const; +}; + +} + + +namespace std { + // Inject comparison and hash function to make pointers behave appropriately with ordered and unordered datastructures + template<> + struct less + { + bool operator()(const loki::pddl::Condition& left_condition, const loki::pddl::Condition& right_condition) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::ConditionLiteralImpl& condition) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::ConditionAndImpl& condition) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::ConditionOrImpl& condition) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::ConditionNotImpl& condition) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::ConditionImplyImpl& condition) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::ConditionExistsImpl& condition) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::ConditionForallImpl& condition) const; + }; +} + + +#endif diff --git a/include/loki/domain/pddl/declarations.hpp b/include/loki/domain/pddl/declarations.hpp new file mode 100644 index 00000000..7c5c522c --- /dev/null +++ b/include/loki/domain/pddl/declarations.hpp @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_PDDL_DECLARATIONS_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_PDDL_DECLARATIONS_HPP_ + +#include "../../common/pddl/declarations.hpp" + +#include + +#include +#include +#include + + +namespace loki::pddl { + class RequirementsImpl; + using Requirements = const RequirementsImpl*; + + class TypeImpl; + using Type = const TypeImpl*; + using TypeList = boost::container::small_vector; // often single type + + class ObjectImpl; + using Object = const ObjectImpl*; + using ObjectList = std::vector; + + class VariableImpl; + using Variable = const VariableImpl*; + using VariableList = std::vector; // not used + using VariableAssignment = std::unordered_map; + + class TermObjectImpl; + class TermVariableImpl; + using TermImpl = std::variant; + using Term = const TermImpl*; + using TermList = boost::container::small_vector; // often unary and binary predicates + + class AtomImpl; + using Atom = const AtomImpl*; + using AtomList = std::vector; + + class ParameterImpl; + using Parameter = const ParameterImpl*; + using ParameterList = boost::container::small_vector; // often actions, quantifiers with few parameters + using ParameterAssignment = std::unordered_map; + + class PredicateImpl; + using Predicate = const PredicateImpl*; + using PredicateList = std::vector; + + class LiteralImpl; + using Literal = const LiteralImpl*; + using LiteralList = std::vector; + + class ConditionLiteralImpl; + class ConditionAndImpl; + class ConditionOrImpl; + class ConditionNotImpl; + class ConditionImplyImpl; + class ConditionExistsImpl; + class ConditionForallImpl; + using ConditionImpl = std::variant; + using Condition = const ConditionImpl*; + using ConditionList = std::vector; + + class EffectLiteralImpl; + class EffectAndImpl; + class EffectNumericImpl; + class EffectConditionalForallImpl; + class EffectConditionalWhenImpl; + using EffectImpl = std::variant; + using Effect = const EffectImpl*; + using EffectList = std::vector; + + class FunctionExpressionNumberImpl; + class FunctionExpressionBinaryOperatorImpl; + class FunctionExpressionMultiOperatorImpl; + class FunctionExpressionMinusImpl; + class FunctionExpressionFunctionImpl; + using FunctionExpressionImpl = std::variant; + using FunctionExpression = const FunctionExpressionImpl*; + using FunctionExpressionList = std::vector; + + class FunctionSkeletonImpl; + using FunctionSkeleton = const FunctionSkeletonImpl*; + using FunctionSkeletonList = std::vector; + + class FunctionImpl; + using Function = const FunctionImpl*; + using FunctionList = std::vector; + + class ConstraintImpl; + using Constraint = const ConstraintImpl*; + using ConstraintList = std::vector; + + class ActionImpl; + using Action = const ActionImpl*; + using ActionList = std::vector; + + class DerivedPredicateImpl; + using DerivedPredicate = const DerivedPredicateImpl*; + using DerivedPredicateList = std::vector; + + class DomainImpl; + using Domain = const DomainImpl*; + using DomainList = std::vector; +} + +#endif diff --git a/include/loki/domain/pddl/derived_predicate.hpp b/include/loki/domain/pddl/derived_predicate.hpp new file mode 100644 index 00000000..8cc866d2 --- /dev/null +++ b/include/loki/domain/pddl/derived_predicate.hpp @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_PDDL_DERIVED_PREDICATE_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_PDDL_DERIVED_PREDICATE_HPP_ + +#include "declarations.hpp" +#include "conditions.hpp" +#include "effects.hpp" + +#include "../../common/pddl/base.hpp" + +#include +#include + + +namespace loki { +template +class PersistentFactory; +} + + +namespace loki::pddl { +class DerivedPredicateImpl : public Base { +private: + ParameterList m_parameters; + Condition m_condition; + + DerivedPredicateImpl(int identifier, ParameterList parameters, Condition condition); + + template + friend class loki::PersistentFactory; + +public: + /// @brief Test for structural equivalence + bool is_structurally_equivalent_to_impl(const DerivedPredicateImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const ParameterList& get_parameters() const; + const Condition& get_condition() const; +}; + +} + + +namespace std { + // Inject comparison and hash function to make pointers behave appropriately with ordered and unordered datastructures + template<> + struct less + { + bool operator()(const loki::pddl::DerivedPredicate& left_predicate, const loki::pddl::DerivedPredicate& right_predicate) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::DerivedPredicateImpl& action) const; + }; +} + + +#endif diff --git a/include/loki/domain/pddl/domain.hpp b/include/loki/domain/pddl/domain.hpp new file mode 100644 index 00000000..f7b9085a --- /dev/null +++ b/include/loki/domain/pddl/domain.hpp @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_PDDL_DOMAIN_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_PDDL_DOMAIN_HPP_ + +#include "declarations.hpp" +#include "requirements.hpp" + +#include "../../common/pddl/base.hpp" + +#include + + +namespace loki { +template +class PersistentFactory; +} + + +namespace loki::pddl { + +class DomainImpl : public Base { +private: + std::string m_name; + Requirements m_requirements; + TypeList m_types; + ObjectList m_constants; + PredicateList m_predicates; + FunctionSkeletonList m_functions; + ActionList m_actions; + + DomainImpl(int identifier, + std::string name, + Requirements requirements, + TypeList types, + ObjectList constants, + PredicateList predicates, + FunctionSkeletonList functions, + ActionList actions); + + template + friend class loki::PersistentFactory; + +public: + /// @brief Test for structural equivalence + bool is_structurally_equivalent_to_impl(const DomainImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const std::string& get_name() const; + const Requirements& get_requirements() const; + const TypeList& get_types() const; + const ObjectList& get_constants() const; + const PredicateList& get_predicates() const; + const FunctionSkeletonList& get_functions() const; + const ActionList& get_actions() const; +}; + +} + + +namespace std { + // Inject comparison and hash function to make pointers behave appropriately with ordered and unordered datastructures + template<> + struct less + { + bool operator()(const loki::pddl::Domain& left_domain, const loki::pddl::Domain& right_domain) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::DomainImpl& domain) const; + }; +} + +#endif diff --git a/include/loki/domain/pddl/effects.hpp b/include/loki/domain/pddl/effects.hpp new file mode 100644 index 00000000..65f3e65a --- /dev/null +++ b/include/loki/domain/pddl/effects.hpp @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_PDDL_EFFECTS_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_PDDL_EFFECTS_HPP_ + +#include "declarations.hpp" + +#include "../../common/pddl/base.hpp" + +#include + + +namespace loki { +template +class PersistentFactory; +} + + +namespace loki::pddl { +enum class AssignOperatorEnum { + ASSIGN, + SCALE_UP, + SCALE_DOWN, + INCREASE, + DECREASE +}; + +extern std::unordered_map assign_operator_enum_to_string; +extern const std::string& to_string(pddl::AssignOperatorEnum assign_operator); + + +/* Literal */ +class EffectLiteralImpl : public Base { +private: + Literal m_literal; + + EffectLiteralImpl(int identifier, Literal literal); + + template + friend class loki::PersistentFactory; + +public: + bool is_structurally_equivalent_to_impl(const EffectLiteralImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const Literal& get_literal() const; +}; + + +/* And */ +class EffectAndImpl : public Base { +private: + EffectList m_effects; + + EffectAndImpl(int identifier, EffectList effects); + + template + friend class loki::PersistentFactory; + +public: + bool is_structurally_equivalent_to_impl(const EffectAndImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const EffectList& get_effects() const; +}; + + +/* EffectNumeric */ +class EffectNumericImpl : public Base { +private: + AssignOperatorEnum m_assign_operator; + Function m_function; + FunctionExpression m_function_expression; + + EffectNumericImpl(int identifier, AssignOperatorEnum assign_operator, Function function, FunctionExpression function_expression); + + template + friend class loki::PersistentFactory; + +public: + bool is_structurally_equivalent_to_impl(const EffectNumericImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + AssignOperatorEnum get_assign_operator() const; + const Function& get_function() const; + const FunctionExpression& get_function_expression() const; +}; + + +/* ConditionalForall */ +class EffectConditionalForallImpl : public Base { +private: + ParameterList m_parameters; + Effect m_effect; + + EffectConditionalForallImpl(int identifier, ParameterList parameters, Effect effect); + + template + friend class loki::PersistentFactory; + +public: + bool is_structurally_equivalent_to_impl(const EffectConditionalForallImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const ParameterList& get_parameters() const; + const Effect& get_effect() const; +}; + + +/* ConditionalWhen */ +class EffectConditionalWhenImpl : public Base { +private: + Condition m_condition; + Effect m_effect; + + EffectConditionalWhenImpl(int identifier, Condition condition, Effect effect); + + template + friend class loki::PersistentFactory; + +public: + bool is_structurally_equivalent_to_impl(const EffectConditionalWhenImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const Condition& get_condition() const; + const Effect& get_effect() const; +}; + + +} + + +namespace std { + // Inject comparison and hash function to make pointers behave appropriately with ordered and unordered datastructures + template<> + struct less + { + bool operator()(const loki::pddl::Effect& left_effect, const loki::pddl::Effect& right_effect) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::EffectLiteralImpl& effect) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::EffectAndImpl& effect) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::EffectNumericImpl& effect) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::EffectConditionalForallImpl& effect) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::EffectConditionalWhenImpl& effect) const; + }; +} + + +#endif diff --git a/include/loki/domain/pddl/exceptions.hpp b/include/loki/domain/pddl/exceptions.hpp new file mode 100644 index 00000000..5df12413 --- /dev/null +++ b/include/loki/domain/pddl/exceptions.hpp @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_PDDL_EXCEPTIONS_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_PDDL_EXCEPTIONS_HPP_ + +#include "declarations.hpp" +#include "requirements.hpp" + +#include "../../common/exceptions.hpp" + +#include + + +namespace loki { + +/* Type */ +class ReservedTypeError : public SemanticParserError { +public: + ReservedTypeError(const std::string& name, const std::string& error_handler_output); +}; + +class UnusedTypeError : public SemanticParserError { +public: + UnusedTypeError(const std::string& name, const std::string& error_handler_output); +}; + +class UndefinedTypeError : public SemanticParserError { +public: + UndefinedTypeError(const std::string& name, const std::string& error_handler_output); +}; + +class MultiDefinitionTypeError : public SemanticParserError { +public: + MultiDefinitionTypeError(const std::string& name, const std::string& error_handler_output); +}; + +/* Predicate */ +class UnusedPredicateError : public SemanticParserError { +public: + UnusedPredicateError(const std::string& name, const std::string& error_handler_output); +}; + +class UndefinedPredicateError : public SemanticParserError { +public: + UndefinedPredicateError(const std::string& name, const std::string& error_handler_output); +}; + +class MultiDefinitionPredicateError : public SemanticParserError { +public: + MultiDefinitionPredicateError(const std::string& name, const std::string& error_handler_output); +}; + +/* Constant */ +// UnusedConstantError is not a valid exception because constants are not required to be used in all problems +class UndefinedConstantError : public SemanticParserError { +public: + UndefinedConstantError(const std::string& name, const std::string& error_handler_output); +}; + +class MultiDefinitionConstantError : public SemanticParserError { +public: + MultiDefinitionConstantError(const std::string& name, const std::string& error_handler_output); +}; + +/* Variable */ +class UnusedVariableError : public SemanticParserError { +public: + UnusedVariableError(const std::string& name, const std::string& error_handler_output); +}; + +class UndefinedVariableError : public SemanticParserError { +public: + UndefinedVariableError(const std::string& name, const std::string& error_handler_output); +}; + +class MultiDefinitionVariableError : public SemanticParserError { +public: + MultiDefinitionVariableError(const std::string& name, const std::string& error_handler_output); +}; + +/* FunctionSkeleton */ +class UnusedFunctionSkeletonError : public SemanticParserError { +public: + UnusedFunctionSkeletonError(const std::string& name, const std::string& error_handler_output); +}; + +class UndefinedFunctionSkeletonError : public SemanticParserError { +public: + UndefinedFunctionSkeletonError(const std::string& name, const std::string& error_handler_output); +}; + +class MultiDefinitionFunctionSkeletonError : public SemanticParserError { +public: + MultiDefinitionFunctionSkeletonError(const std::string& name, const std::string& error_handler_output); +}; + +/* Requirement */ +class UnusedRequirementError : public SemanticParserError { +public: + UnusedRequirementError(pddl::RequirementEnum requirement, const std::string& error_handler_output); +}; + +class UndefinedRequirementError : public SemanticParserError { +public: + UndefinedRequirementError(pddl::RequirementEnum requirement, const std::string& error_handler_output); +}; + +class UnsupportedRequirementError : public std::runtime_error { +public: + explicit UnsupportedRequirementError(pddl::RequirementEnum requirement, const std::string& error_handler_output); +}; + + +/* Compatibility errors */ +class MismatchedPredicateTermListError : public SemanticParserError { +public: + MismatchedPredicateTermListError( + const pddl::Predicate& predicate, + const pddl::TermList& term_list, + const std::string& error_handler_output); +}; + +class MismatchedFunctionSkeletonTermListError : public SemanticParserError { +public: + MismatchedFunctionSkeletonTermListError( + const pddl::FunctionSkeleton& function_skeleton, + const pddl::TermList& term_list, + const std::string& error_handler_output); +}; + +} + +#endif \ No newline at end of file diff --git a/include/loki/domain/pddl/function.hpp b/include/loki/domain/pddl/function.hpp new file mode 100644 index 00000000..51931154 --- /dev/null +++ b/include/loki/domain/pddl/function.hpp @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_PDDL_FUNCTION_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_PDDL_FUNCTION_HPP_ + +#include "declarations.hpp" + +#include "../../common/pddl/base.hpp" + +#include + + +namespace loki { +template +class PersistentFactory; +} + + +namespace loki::pddl { +class FunctionImpl : public Base { +private: + FunctionSkeleton m_function_skeleton; + TermList m_terms; + + FunctionImpl(int identifier, FunctionSkeleton function_skeleton, TermList terms); + + template + friend class loki::PersistentFactory; + +public: + /// @brief Test for semantic equivalence + bool is_structurally_equivalent_to_impl(const FunctionImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const FunctionSkeleton& get_function_skeleton() const; + const TermList& get_terms() const; +}; + +} + + +namespace std { + // Inject comparison and hash function to make pointers behave appropriately with ordered and unordered datastructures + template<> + struct less + { + bool operator()(const loki::pddl::Function& left_function, const loki::pddl::Function& right_function) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::FunctionImpl& function) const; + }; +} + +#endif diff --git a/include/loki/domain/pddl/function_expressions.hpp b/include/loki/domain/pddl/function_expressions.hpp new file mode 100644 index 00000000..1394c402 --- /dev/null +++ b/include/loki/domain/pddl/function_expressions.hpp @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_PDDL_FUNCTION_EXPRESSIONS_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_PDDL_FUNCTION_EXPRESSIONS_HPP_ + +#include "declarations.hpp" + +#include "../../common/pddl/base.hpp" + +#include + + +namespace loki { +template +class PersistentFactory; +} + + +namespace loki::pddl { +enum class BinaryOperatorEnum { + MUL, + PLUS, + MINUS, + DIV, +}; + +extern std::unordered_map binary_operator_enum_to_string; +extern const std::string& to_string(pddl::BinaryOperatorEnum binary_operator); + +enum class MultiOperatorEnum { + MUL, + PLUS, +}; + +extern std::unordered_map multi_operator_enum_to_string; +extern const std::string& to_string(pddl::MultiOperatorEnum multi_operator); + + +/* FunctionExpressionNumber */ +class FunctionExpressionNumberImpl : public Base { +private: + double m_number; + + FunctionExpressionNumberImpl(int identifier, double number); + + template + friend class loki::PersistentFactory; + +public: + bool is_structurally_equivalent_to_impl(const FunctionExpressionNumberImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + double get_number() const; +}; + + +/* FunctionExpressionBinaryOperator */ +class FunctionExpressionBinaryOperatorImpl : public Base { +private: + BinaryOperatorEnum m_binary_operator; + FunctionExpression m_left_function_expression; + FunctionExpression m_right_function_expression; + + FunctionExpressionBinaryOperatorImpl(int identifier, + BinaryOperatorEnum binary_operator, + FunctionExpression left_function_expression, + FunctionExpression right_function_expression); + + template + friend class loki::PersistentFactory; + +public: + bool is_structurally_equivalent_to_impl(const FunctionExpressionBinaryOperatorImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + BinaryOperatorEnum get_binary_operator() const; + const FunctionExpression& get_left_function_expression() const; + const FunctionExpression& get_right_function_expression() const; +}; + + +/* FunctionExpressionMultiOperator */ +class FunctionExpressionMultiOperatorImpl : public Base { +private: + MultiOperatorEnum m_multi_operator; + FunctionExpressionList m_function_expressions; + + FunctionExpressionMultiOperatorImpl(int identifier, + MultiOperatorEnum multi_operator, + FunctionExpressionList function_expressions); + + template + friend class loki::PersistentFactory; + +public: + bool is_structurally_equivalent_to_impl(const FunctionExpressionMultiOperatorImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + MultiOperatorEnum get_multi_operator() const; + const FunctionExpressionList& get_function_expressions() const; +}; + + +/* FunctionExpressionMinus */ +class FunctionExpressionMinusImpl : public Base { +private: + FunctionExpression m_function_expression; + + FunctionExpressionMinusImpl(int identifier, FunctionExpression function_expression); + + template + friend class loki::PersistentFactory; + +public: + bool is_structurally_equivalent_to_impl(const FunctionExpressionMinusImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const FunctionExpression& get_function_expression() const; +}; + + +/* FunctionExpressionFunction */ +class FunctionExpressionFunctionImpl : public Base { +private: + Function m_function; + + FunctionExpressionFunctionImpl(int identifier, Function function); + + template + friend class loki::PersistentFactory; + +public: + bool is_structurally_equivalent_to_impl(const FunctionExpressionFunctionImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const Function& get_function() const; +}; + +} + + +namespace std { + // Inject comparison and hash function to make pointers behave appropriately with ordered and unordered datastructures + template<> + struct less + { + bool operator()(const loki::pddl::FunctionExpression& left_function_expression, const loki::pddl::FunctionExpression& right_function_expression) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::FunctionExpressionNumberImpl& function_expressions) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::FunctionExpressionBinaryOperatorImpl& function_expressions) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::FunctionExpressionMultiOperatorImpl& function_expressions) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::FunctionExpressionMinusImpl& function_expressions) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::FunctionExpressionFunctionImpl& function_expressions) const; + }; +} + +#endif diff --git a/include/loki/domain/pddl/function_skeleton.hpp b/include/loki/domain/pddl/function_skeleton.hpp new file mode 100644 index 00000000..46ef67a3 --- /dev/null +++ b/include/loki/domain/pddl/function_skeleton.hpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_PDDL_FUNCTION_SKELETON_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_PDDL_FUNCTION_SKELETON_HPP_ + +#include "declarations.hpp" + +#include "../../common/pddl/base.hpp" + +#include + + +namespace loki { +template +class PersistentFactory; +} + + +namespace loki::pddl { +class FunctionSkeletonImpl : public Base { +private: + std::string m_name; + ParameterList m_parameters; + Type m_type; + + FunctionSkeletonImpl(int identifier, std::string name, ParameterList parameters, Type type); + + template + friend class loki::PersistentFactory; + +public: + /// @brief Test for semantic equivalence + bool is_structurally_equivalent_to_impl(const FunctionSkeletonImpl& other) const; + size_t hash_impl() const; + /// @brief Returns a string representation where typing is assumed to be true. + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + /// @brief Returns a parseable string representation in the context of a domain. + void str(std::ostringstream& out, const FormattingOptions& options, bool typing_enabled) const; + + const std::string& get_name() const; + const ParameterList& get_parameters() const; + const Type& get_type() const; +}; + +} + + +namespace std { + // Inject comparison and hash function to make pointers behave appropriately with ordered and unordered datastructures + template<> + struct less + { + bool operator()(const loki::pddl::FunctionSkeleton& left_function, const loki::pddl::FunctionSkeleton& right_function) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::FunctionSkeletonImpl& function) const; + }; +} + +#endif diff --git a/include/loki/domain/pddl/literal.hpp b/include/loki/domain/pddl/literal.hpp new file mode 100644 index 00000000..dbe94081 --- /dev/null +++ b/include/loki/domain/pddl/literal.hpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_PROBLEM_PDDL_LITERAL_HPP_ +#define LOKI_INCLUDE_LOKI_PROBLEM_PDDL_LITERAL_HPP_ + +#include "declarations.hpp" + +#include "../../common/pddl/base.hpp" + + +namespace loki { +template +class PersistentFactory; +} + + +namespace loki::pddl { +class LiteralImpl : public Base { +private: + bool m_is_negated; + Atom m_atom; + + LiteralImpl(int identifier, bool is_negated, Atom atom); + + template + friend class loki::PersistentFactory; + +public: + /// @brief Test for semantic equivalence + bool is_structurally_equivalent_to_impl(const LiteralImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + bool is_negated() const; + const Atom& get_atom() const; +}; + +} + + +namespace std { + // Inject comparison and hash function to make pointers behave appropriately with ordered and unordered datastructures + template<> + struct less + { + bool operator()(const loki::pddl::Literal& left_literal, const loki::pddl::Literal& right_literal) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::LiteralImpl& literal) const; + }; +} + + +#endif diff --git a/include/loki/domain/pddl/object.hpp b/include/loki/domain/pddl/object.hpp new file mode 100644 index 00000000..91f4a415 --- /dev/null +++ b/include/loki/domain/pddl/object.hpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_PDDL_OBJECT_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_PDDL_OBJECT_HPP_ + +#include "declarations.hpp" + +#include "../../common/pddl/base.hpp" + +#include +#include + + +namespace loki { +template +class PersistentFactory; +} + + +namespace loki::pddl { +class ObjectImpl : public Base { +private: + std::string m_name; + TypeList m_types; + + ObjectImpl(int identifier, std::string name, TypeList types={}); + + template + friend class loki::PersistentFactory; + +public: + /// @brief Test for semantic equivalence + bool is_structurally_equivalent_to_impl(const ObjectImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const std::string& get_name() const; + const TypeList& get_bases() const; +}; + +} + + +namespace std { + // Inject comparison and hash function to make pointers behave appropriately with ordered and unordered datastructures + template<> + struct less + { + bool operator()(const loki::pddl::Object& left_object, const loki::pddl::Object& right_object) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::ObjectImpl& object) const; + }; +} + + +#endif diff --git a/include/loki/domain/pddl/parameter.hpp b/include/loki/domain/pddl/parameter.hpp new file mode 100644 index 00000000..94e73125 --- /dev/null +++ b/include/loki/domain/pddl/parameter.hpp @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_PDDL_PARAMETER_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_PDDL_PARAMETER_HPP_ + +#include "declarations.hpp" + +#include "../../common/pddl/base.hpp" + +#include + + +namespace loki { +template +class PersistentFactory; +} + + +namespace loki::pddl { + +class ParameterImpl : public Base { +private: + Variable m_variable; + TypeList m_types; + + ParameterImpl(int identifier, Variable variable, TypeList types); + + template + friend class loki::PersistentFactory; + +public: + /// @brief Test for semantic equivalence + bool is_structurally_equivalent_to_impl(const ParameterImpl& other) const; + size_t hash_impl() const; + /// @brief Returns a string representation where typing is assumed to be true. + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + /// @brief Returns a parseable string representation in the context of a domain. + void str(std::ostringstream& out, const FormattingOptions& options, bool typing_enabled) const; + + const Variable& get_variable() const; + const TypeList& get_bases() const; +}; + +} + + +namespace std { + // Inject comparison and hash function to make pointers behave appropriately with ordered and unordered datastructures + template<> + struct less + { + bool operator()(const loki::pddl::Parameter& left_parameter, const loki::pddl::Parameter& right_parameter) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::ParameterImpl& parameter) const; + }; +} + +#endif diff --git a/include/loki/domain/pddl/parser.hpp b/include/loki/domain/pddl/parser.hpp new file mode 100644 index 00000000..2242c093 --- /dev/null +++ b/include/loki/domain/pddl/parser.hpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_PDDL_PARSER_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_PDDL_PARSER_HPP_ + +#include "../../common/pddl/context.hpp" +#include "declarations.hpp" + +#include "../ast/ast.hpp" + + +namespace loki { + +extern pddl::Domain parse(const domain::ast::Domain& domain_node, Context& context); + +} + +#endif diff --git a/include/loki/domain/pddl/predicate.hpp b/include/loki/domain/pddl/predicate.hpp new file mode 100644 index 00000000..d27dd5f3 --- /dev/null +++ b/include/loki/domain/pddl/predicate.hpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_PDDL_PREDICATE_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_PDDL_PREDICATE_HPP_ + +#include "declarations.hpp" + +#include "../../common/pddl/base.hpp" + +#include + + +namespace loki { +template +class PersistentFactory; +} + + +namespace loki::pddl { + +// An alternative name is AtomSkeleton +class PredicateImpl : public Base { +private: + std::string m_name; + ParameterList m_parameters; + + PredicateImpl(int identifier, std::string name, ParameterList parameters); + + template + friend class loki::PersistentFactory; + +public: + /// @brief Test for semantic equivalence + bool is_structurally_equivalent_to_impl(const PredicateImpl& other) const; + size_t hash_impl() const; + /// @brief Returns a string representation where typing is assumed to be true. + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + /// @brief Returns a parseable string representation in the context of a domain. + void str(std::ostringstream& out, const FormattingOptions& options, bool typing_enabled) const; + + const std::string& get_name() const; + const ParameterList& get_parameters() const; +}; + +} + + +namespace std { + // Inject comparison and hash function to make pointers behave appropriately with ordered and unordered datastructures + template<> + struct less + { + bool operator()(const loki::pddl::Predicate& left_predicate, const loki::pddl::Predicate& right_predicate) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::PredicateImpl& predicate) const; + }; +} + +#endif diff --git a/include/loki/domain/pddl/requirements.hpp b/include/loki/domain/pddl/requirements.hpp new file mode 100644 index 00000000..cf9d87b9 --- /dev/null +++ b/include/loki/domain/pddl/requirements.hpp @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_PDDL_REQUIREMENTS_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_PDDL_REQUIREMENTS_HPP_ + +#include "declarations.hpp" + +#include "../../common/pddl/base.hpp" + +#include +#include +#include + + +namespace loki { +template +class PersistentFactory; +} + + +namespace loki::pddl { +enum class RequirementEnum { + STRIPS, + TYPING, + NEGATIVE_PRECONDITIONS, + DISJUNCTIVE_PRECONDITIONS, + EQUALITY, + EXISTENTIAL_PRECONDITIONS, + UNIVERSAL_PRECONDITIONS, + QUANTIFIED_PRECONDITIONS, + CONDITIONAL_EFFECTS, + FLUENTS, + OBJECT_FLUENTS, + NUMERIC_FLUENTS, + ADL, + DURATIVE_ACTIONS, + DERIVED_PREDICATES, + TIMED_INITIAL_LITERALS, + PREFERENCES, + CONSTRAINTS, + ACTION_COSTS, +}; + +using RequirementEnumSet = std::set; +using RequirementEnumList = std::vector; + +extern std::unordered_map requirement_enum_to_string; +extern const std::string& to_string(pddl::RequirementEnum requirement); + + +class RequirementsImpl : public Base { +private: + RequirementEnumSet m_requirements; + + RequirementsImpl(int identifier, RequirementEnumSet requirements); + + template + friend class loki::PersistentFactory; + +public: + /// @brief Test for semantic equivalence + bool is_structurally_equivalent_to_impl(const RequirementsImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + bool test(RequirementEnum requirement) const; + + const RequirementEnumSet& get_requirements() const; +}; + +} + + +namespace std { + // Inject comparison and hash function to make pointers behave appropriately with ordered and unordered datastructures + template<> + struct less + { + bool operator()(const loki::pddl::Requirements& left_requirements, const loki::pddl::Requirements& right_requirements) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::RequirementsImpl& requirements) const; + }; +} + +#endif diff --git a/include/loki/domain/pddl/term.hpp b/include/loki/domain/pddl/term.hpp new file mode 100644 index 00000000..f275562d --- /dev/null +++ b/include/loki/domain/pddl/term.hpp @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_PDDL_TERM_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_PDDL_TERM_HPP_ + +#include "declarations.hpp" + +#include "../../common/pddl/base.hpp" + + +namespace loki { +template +class PersistentFactory; +} + + + +namespace loki::pddl { + +class TermObjectImpl : public Base { +private: + Object m_object; + + TermObjectImpl(int identifier, Object object); + + template + friend class loki::PersistentFactory; + +public: + bool is_structurally_equivalent_to_impl(const TermObjectImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const Object& get_object() const; +}; + + +class TermVariableImpl : public Base { +private: + Variable m_variable; + + TermVariableImpl(int identifier, Variable variable); + + template + friend class loki::PersistentFactory; + +public: + bool is_structurally_equivalent_to_impl(const TermVariableImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const Variable& get_variable() const; +}; + +} + + + +namespace std { + // Inject comparison and hash function to make pointers behave appropriately with ordered and unordered datastructures + template<> + struct less + { + bool operator()(const loki::pddl::Term& left_term, const loki::pddl::Term& right_term) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::TermObjectImpl& term) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::TermVariableImpl& term) const; + }; +} + +#endif diff --git a/include/loki/domain/pddl/type.hpp b/include/loki/domain/pddl/type.hpp new file mode 100644 index 00000000..ec863a33 --- /dev/null +++ b/include/loki/domain/pddl/type.hpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_PDDL_TYPE_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_PDDL_TYPE_HPP_ + +#include "declarations.hpp" + +#include "../../common/pddl/base.hpp" + +#include + + +namespace loki { +template +class PersistentFactory; +} + + +namespace loki::pddl { +class TypeImpl : public Base { +private: + std::string m_name; + TypeList m_bases; + + TypeImpl(int identifier, std::string name, TypeList bases = {}); + + template + friend class loki::PersistentFactory; + +public: + /// @brief Test for semantic equivalence + bool is_structurally_equivalent_to_impl(const TypeImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const std::string& get_name() const; + const TypeList& get_bases() const; +}; +} + + +namespace std { + // Inject comparison and hash function to make pointers behave appropriately with ordered and unordered datastructures + template<> + struct less + { + bool operator()(const loki::pddl::Type& left_type, const loki::pddl::Type& right_type) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::TypeImpl& type) const; + }; +} + +#endif diff --git a/include/loki/domain/pddl/variable.hpp b/include/loki/domain/pddl/variable.hpp new file mode 100644 index 00000000..806b3d0d --- /dev/null +++ b/include/loki/domain/pddl/variable.hpp @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_DOMAIN_PDDL_VARIABLE_HPP_ +#define LOKI_INCLUDE_LOKI_DOMAIN_PDDL_VARIABLE_HPP_ + +#include "declarations.hpp" + +#include "../../common/pddl/base.hpp" + + +namespace loki { +template +class PersistentFactory; +} + + +namespace loki::pddl { +class VariableImpl : public Base { +private: + std::string m_name; + + VariableImpl(int identifier, std::string name); + + template + friend class loki::PersistentFactory; + +public: + /// @brief Test for semantic equivalence + bool is_structurally_equivalent_to_impl(const VariableImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const std::string& get_name() const; +}; + +} + + +namespace std { + // Inject comparison and hash function to make pointers behave appropriately with ordered and unordered datastructures + template<> + struct less + { + bool operator()(const loki::pddl::Variable& left_variable, const loki::pddl::Variable& right_variable) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::VariableImpl& variable) const; + }; +} + + +#endif diff --git a/include/loki/problem/ast/ast.hpp b/include/loki/problem/ast/ast.hpp new file mode 100644 index 00000000..2e61c821 --- /dev/null +++ b/include/loki/problem/ast/ast.hpp @@ -0,0 +1,308 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_PROBLEM_AST_AST_HPP_ +#define LOKI_INCLUDE_LOKI_PROBLEM_AST_AST_HPP_ + +#include "../../domain/ast/ast.hpp" + +#include +#include +#include + +#include +#include + + +namespace loki::problem::ast +{ + /////////////////////////////////////////////////////////////////////////// + // The AST + /////////////////////////////////////////////////////////////////////////// + namespace x3 = boost::spirit::x3; + + struct BasicFunctionTerm; + + struct AtomicFormulaOfNamesPredicate; + struct AtomicFormulaOfNamesEquality; // :equality + struct AtomicFormulaOfNames; + struct Atom; + struct NegatedAtom; + struct Literal; + + struct InitialElementLiteral; + struct InitialElementTimedLiterals; // :timed-initial-literals + struct InitialElementNumericFluentsTotalCost; // :action-costs + struct InitialElementNumericFluentsGeneral; // :numeric-fluents + struct InitialElement; + + struct MetricFunctionExpression; + struct MetricFunctionExpressionNumber; + struct MetricFunctionExpressionBinaryOperator; + struct MetricFunctionExpressionMultiOperator; + struct MetricFunctionExpressionMinus; + struct MetricFunctionExpressionBasicFunctionTerm; + struct MetricFunctionExpressionTotalTime; + struct MetricFunctionExpressionPreferences; // :preferences + + struct OptimizationMinimize; + struct OptimizationMaximize; + struct Optimization; + struct MetricSpecificationTotalCost; + struct MetricSpecificationGeneral; + + struct PreferenceConstraintGoalDescriptor; + struct PreferenceConstraintGoalDescriptorAnd; + struct PreferenceConstraintGoalDescriptorForall; // :universal-preconditions + struct PreferenceConstraintGoalDescriptorPreference; // :preferences + struct PreferenceConstraintGoalDescriptorSimple; + + struct ProblemName; + struct DomainName; + struct Objects; + struct Initial; + struct Goal; + struct Constraints; // :constraints + struct MetricSpecification; // :numeric-fluents + + struct Problem; + + + /* */ + struct BasicFunctionTerm : x3::position_tagged { + domain::ast::FunctionSymbol function_symbol; + std::vector names; + }; + + + /* Atomic formulas */ + struct AtomicFormulaOfNamesPredicate : x3::position_tagged + { + domain::ast::Predicate predicate; + std::vector names; + }; + + struct AtomicFormulaOfNamesEquality : x3::position_tagged + { + domain::ast::Name name_left; + domain::ast::Name name_right; + }; + + struct AtomicFormulaOfNames : x3::position_tagged, + x3::variant< + AtomicFormulaOfNamesPredicate, + AtomicFormulaOfNamesEquality> + { + using base_type::base_type; + using base_type::operator=; + }; + + struct Atom : x3::position_tagged + { + AtomicFormulaOfNames atomic_formula_of_names; + }; + + struct NegatedAtom : x3::position_tagged + { + AtomicFormulaOfNames atomic_formula_of_names; + }; + + struct Literal : x3::position_tagged, + x3::variant< + Atom, + NegatedAtom> + { + using base_type::base_type; + using base_type::operator=; + }; + + /* */ + struct InitialElementLiteral : x3::position_tagged { + Literal literal; + }; + + struct InitialElementTimedLiterals : x3::position_tagged { + domain::ast::Number number; + Literal literal; + }; + + struct InitialElementNumericFluentsTotalCost : x3::position_tagged { + domain::ast::FunctionSymbol function_symbol_total_cost; + domain::ast::Number number; + }; + + struct InitialElementNumericFluentsGeneral : x3::position_tagged { + BasicFunctionTerm basic_function_term; + domain::ast::Number number; + }; + + struct InitialElement : x3::position_tagged, + x3::variant< + InitialElementLiteral, + InitialElementTimedLiterals, + InitialElementNumericFluentsTotalCost, + InitialElementNumericFluentsGeneral> { + using base_type::base_type; + using base_type::operator=; + }; + + + /* */ + struct MetricFunctionExpression : x3::position_tagged, + x3::variant< + x3::forward_ast, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast> { + using base_type::base_type; + using base_type::operator=; + }; + + struct MetricFunctionExpressionNumber : x3::position_tagged { + domain::ast::Number number; + }; + + struct MetricFunctionExpressionBinaryOperator : x3::position_tagged { + domain::ast::BinaryOperator binary_operator; + MetricFunctionExpression metric_function_expression_left; + MetricFunctionExpression metric_function_expression_right; + }; + + struct MetricFunctionExpressionMultiOperator : x3::position_tagged { + domain::ast::MultiOperator multi_operator; + MetricFunctionExpression metric_function_expression_first; + std::vector metric_function_expression_remaining; + }; + + struct MetricFunctionExpressionMinus : x3::position_tagged { + MetricFunctionExpression metric_function_expression; + }; + + struct MetricFunctionExpressionBasicFunctionTerm : x3::position_tagged { + BasicFunctionTerm basic_function_term; + }; + + struct MetricFunctionExpressionTotalTime : x3::position_tagged { }; + + struct MetricFunctionExpressionPreferences : x3::position_tagged { + domain::ast::PreferenceName preference_name; + }; + + + /* */ + struct OptimizationMinimize : x3::position_tagged { }; + + struct OptimizationMaximize : x3::position_tagged { }; + + struct Optimization : x3::position_tagged, + x3::variant< + OptimizationMinimize, + OptimizationMaximize> { + using base_type::base_type; + using base_type::operator=; + }; + + struct MetricSpecificationTotalCost : x3::position_tagged { + OptimizationMinimize optimization_minimize; + domain::ast::FunctionSymbol function_symbol_total_cost; + }; + + struct MetricSpecificationGeneral : x3::position_tagged { + Optimization optimization; + MetricFunctionExpression metric_function_expression; + }; + + + /* */ + struct PreferenceConstraintGoalDescriptor : x3::position_tagged, + x3::variant< + x3::forward_ast, + x3::forward_ast, + x3::forward_ast, + x3::forward_ast> { + using base_type::base_type; + using base_type::operator=; + }; + + struct PreferenceConstraintGoalDescriptorAnd : x3::position_tagged { + std::vector preference_constraint_goal_descriptors; + }; + + struct PreferenceConstraintGoalDescriptorForall : x3::position_tagged { + domain::ast::TypedListOfVariables typed_list_of_variables; + PreferenceConstraintGoalDescriptor preference_constraint_goal_descriptor; + }; + + struct PreferenceConstraintGoalDescriptorPreference : x3::position_tagged { + boost::optional preference_name; + domain::ast::ConstraintGoalDescriptor constraint_goal_descriptor; + }; + + struct PreferenceConstraintGoalDescriptorSimple : x3::position_tagged { + domain::ast::ConstraintGoalDescriptor constraint_goal_descriptor; + }; + + + /* */ + struct ProblemName : x3::position_tagged { + domain::ast::Name name; + }; + + struct DomainName : x3::position_tagged { + domain::ast::Name name; + }; + + struct Objects : x3::position_tagged { + domain::ast::TypedListOfNames typed_list_of_names; + }; + + struct Initial : x3::position_tagged { + std::vector initial_elements; + }; + + struct Goal : x3::position_tagged { + domain::ast::PreconditionGoalDescriptor precondition_goal_descriptor; + }; + + struct Constraints : x3::position_tagged { + PreferenceConstraintGoalDescriptor preference_constraint_goal_descriptor; + }; + + struct MetricSpecification : x3::position_tagged, + x3::variant { + using base_type::base_type; + using base_type::operator=; + }; + + struct Problem : x3::position_tagged { + ProblemName problem_name; + DomainName domain_name; + boost::optional requirements; + boost::optional objects; + Initial initial; + Goal goal; + boost::optional constraints; + boost::optional metric_specification; + }; + +} + +#endif \ No newline at end of file diff --git a/include/loki/problem/ast/error_handler.hpp b/include/loki/problem/ast/error_handler.hpp new file mode 100644 index 00000000..41133f01 --- /dev/null +++ b/include/loki/problem/ast/error_handler.hpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_PROBLEM_AST_ERROR_HANDLER_HPP_ +#define LOKI_INCLUDE_LOKI_PROBLEM_AST_ERROR_HANDLER_HPP_ + +#include "../../domain/ast/error_handler.hpp" + +#include +#include + + +namespace loki::problem +{ + namespace x3 = boost::spirit::x3; + + struct error_handler_problem : domain::error_handler_domain { + error_handler_problem() : domain::error_handler_domain() { + id_map["name"] = "Name"; + } + }; +} + +#endif diff --git a/include/loki/problem/ast/parser.hpp b/include/loki/problem/ast/parser.hpp new file mode 100644 index 00000000..cf69e257 --- /dev/null +++ b/include/loki/problem/ast/parser.hpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_PROBLEM_AST_PARSER_HPP_ +#define LOKI_INCLUDE_LOKI_PROBLEM_AST_PARSER_HPP_ + +#include "ast.hpp" + +#include + + +namespace loki::problem +{ + namespace x3 = boost::spirit::x3; + + /////////////////////////////////////////////////////////////////////////// + // parser public interface + /////////////////////////////////////////////////////////////////////////// + namespace parser { + struct ProblemClass; + + typedef x3::rule problem_type; + + BOOST_SPIRIT_DECLARE(problem_type) + } + + parser::problem_type const& problem(); +} + +#endif \ No newline at end of file diff --git a/include/loki/problem/ast/printer.hpp b/include/loki/problem/ast/printer.hpp new file mode 100644 index 00000000..5aff8779 --- /dev/null +++ b/include/loki/problem/ast/printer.hpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_PROBLEM_AST_PRINTER_HPP_ +#define LOKI_INCLUDE_LOKI_PROBLEM_AST_PRINTER_HPP_ + +#include "ast.hpp" +#include "../../common/printer.hpp" + + +namespace loki { + +// create string representations from ast nodes. +extern std::string parse_text(const problem::ast::BasicFunctionTerm& node, const FormattingOptions& options={}); + +extern std::string parse_text(const problem::ast::AtomicFormulaOfNamesPredicate& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::AtomicFormulaOfNamesEquality& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::AtomicFormulaOfNames& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::Atom& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::NegatedAtom& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::Literal& node, const FormattingOptions& options={}); + +extern std::string parse_text(const problem::ast::InitialElementLiteral& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::InitialElementTimedLiterals& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::InitialElementNumericFluentsTotalCost& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::InitialElementNumericFluentsGeneral& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::InitialElement& node, const FormattingOptions& options={}); + +extern std::string parse_text(const problem::ast::MetricFunctionExpression& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::MetricFunctionExpressionNumber& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::MetricFunctionExpressionBinaryOperator& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::MetricFunctionExpressionMultiOperator& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::MetricFunctionExpressionMinus& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::MetricFunctionExpressionBasicFunctionTerm& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::MetricFunctionExpressionTotalTime& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::MetricFunctionExpressionPreferences& node, const FormattingOptions& options={}); + +extern std::string parse_text(const problem::ast::OptimizationMinimize& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::OptimizationMaximize& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::Optimization& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::MetricSpecificationTotalCost& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::MetricSpecificationGeneral& node, const FormattingOptions& options={}); + +extern std::string parse_text(const problem::ast::PreferenceConstraintGoalDescriptor& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::PreferenceConstraintGoalDescriptorAnd& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::PreferenceConstraintGoalDescriptorForall& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::PreferenceConstraintGoalDescriptorPreference& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::PreferenceConstraintGoalDescriptorSimple& node, const FormattingOptions& options={}); + +extern std::string parse_text(const problem::ast::ProblemName& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::DomainName& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::Objects& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::Initial& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::Goal& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::Constraints& node, const FormattingOptions& options={}); +extern std::string parse_text(const problem::ast::MetricSpecification& node, const FormattingOptions& options={}); + +extern std::string parse_text(const problem::ast::Problem& node, const FormattingOptions& options={}); + +} + +#endif \ No newline at end of file diff --git a/include/loki/problem/parser.hpp b/include/loki/problem/parser.hpp new file mode 100644 index 00000000..1555a4bf --- /dev/null +++ b/include/loki/problem/parser.hpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_PROBLEM_PARSER_HPP_ +#define LOKI_INCLUDE_LOKI_PROBLEM_PARSER_HPP_ + +#include "pddl/declarations.hpp" + +#include "../common/pddl/context.hpp" +#include "../common/filesystem.hpp" +#include "../domain/parser.hpp" + + +namespace loki { + +class ProblemParser { +private: + fs::path m_file_path; + // We need to keep the source in memory for error reporting. + std::string m_source; + + // The matched positions in the input PDDL file. + std::unique_ptr m_position_cache; + + std::unique_ptr m_scopes; + + // Parsed result + pddl::Problem m_problem; + +public: + explicit ProblemParser(const fs::path& file_path, DomainParser& domain_parser); + + /// @brief Get position caches to be able to reference back to the input PDDL file. + const PDDLPositionCache& get_position_cache() const; + + /// @brief Get the parsed problem. + const pddl::Problem& get_problem() const; +}; + +} + +#endif \ No newline at end of file diff --git a/include/loki/problem/pddl/declarations.hpp b/include/loki/problem/pddl/declarations.hpp new file mode 100644 index 00000000..ea562469 --- /dev/null +++ b/include/loki/problem/pddl/declarations.hpp @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_PROBLEM_PDDL_DECLARATIONS_HPP_ +#define LOKI_INCLUDE_LOKI_PROBLEM_PDDL_DECLARATIONS_HPP_ + +#include "../../domain/pddl/declarations.hpp" + +#include + + +namespace loki::pddl { + class NumericFluentImpl; + using NumericFluent = const NumericFluentImpl*; + using NumericFluentList = std::vector; + + class OptimizationMetricImpl; + using OptimizationMetric = const OptimizationMetricImpl*; + + class ProblemImpl; + using Problem = const ProblemImpl*; + using ProblemList = std::vector; +} + +#endif diff --git a/include/loki/problem/pddl/exceptions.hpp b/include/loki/problem/pddl/exceptions.hpp new file mode 100644 index 00000000..21a2eec4 --- /dev/null +++ b/include/loki/problem/pddl/exceptions.hpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_PROBLEM_PDDL_EXCEPTIONS_HPP_ +#define LOKI_INCLUDE_LOKI_PROBLEM_PDDL_EXCEPTIONS_HPP_ + +#include "declarations.hpp" +#include "../../common/exceptions.hpp" + +#include + + +namespace loki { +/* Object */ +class UnusedObjectError : public SemanticParserError { +public: + UnusedObjectError(const std::string& name, const std::string& error_handler_output); +}; + +class UndefinedObjectError : public SemanticParserError { +public: + UndefinedObjectError(const std::string& name, const std::string& error_handler_output); +}; + +class MultiDefinitionObjectError : public SemanticParserError { +public: + MultiDefinitionObjectError(const std::string& name, const std::string& error_handler_output); +}; + +/* Compatibility errors */ +class MismatchedDomainError : public SemanticParserError { +public: + MismatchedDomainError( + const pddl::Domain& domain, + const std::string& domain_name, + const std::string& error_handler_output); +}; + +class MismatchedPredicateObjectListError : public SemanticParserError { +public: + MismatchedPredicateObjectListError( + const pddl::Predicate& predicate, + const pddl::ObjectList& object_list, + const std::string& error_handler_output); +}; + +class NegativeCostError : public SemanticParserError { +public: + NegativeCostError( + const std::string& error_handler_output); +}; + +} + +#endif \ No newline at end of file diff --git a/include/loki/problem/pddl/metric.hpp b/include/loki/problem/pddl/metric.hpp new file mode 100644 index 00000000..fcf543ab --- /dev/null +++ b/include/loki/problem/pddl/metric.hpp @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_PROBLEM_PDDL_METRIC_HPP_ +#define LOKI_INCLUDE_LOKI_PROBLEM_PDDL_METRIC_HPP_ + +#include "declarations.hpp" + +#include "../../common/pddl/base.hpp" + + +namespace loki { +template +class PersistentFactory; +} + + +namespace loki::pddl { +enum class OptimizationMetricEnum { + MINIMIZE, + MAXIMIZE +}; + +extern std::unordered_map optimization_metric_enum_to_string; +extern const std::string& to_string(pddl::OptimizationMetricEnum optimization_metric); + + +class OptimizationMetricImpl : public Base { +private: + OptimizationMetricEnum m_optimization_metric; + FunctionExpression m_function_expression; + + template + friend class loki::PersistentFactory; + +public: + OptimizationMetricImpl(int identifier, OptimizationMetricEnum optimization_metric, FunctionExpression function_expression); + + /// @brief Test for semantic equivalence + bool is_structurally_equivalent_to_impl(const OptimizationMetricImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + OptimizationMetricEnum get_optimization_metric() const; + const FunctionExpression& get_function_expression() const; +}; + +} + + +namespace std { + // Inject comparison and hash function to make pointers behave appropriately with ordered and unordered datastructures + template<> + struct less + { + bool operator()(const loki::pddl::OptimizationMetric& left_metric, const loki::pddl::OptimizationMetric& right_metric) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::OptimizationMetricImpl& metric) const; + }; +} + +#endif diff --git a/include/loki/problem/pddl/numeric_fluent.hpp b/include/loki/problem/pddl/numeric_fluent.hpp new file mode 100644 index 00000000..57ab316e --- /dev/null +++ b/include/loki/problem/pddl/numeric_fluent.hpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_PROBLEM_PDDL_NUMERIC_FLUENT_HPP_ +#define LOKI_INCLUDE_LOKI_PROBLEM_PDDL_NUMERIC_FLUENT_HPP_ + +#include "declarations.hpp" + +#include "../../common/pddl/base.hpp" +#include "../../domain/pddl/function.hpp" + + +namespace loki { +template +class PersistentFactory; +} + + +namespace loki::pddl { +class NumericFluentImpl : public Base { +private: + Function m_function; + double m_number; + + template + friend class loki::PersistentFactory; + +public: + NumericFluentImpl(int identifier, Function function, double number); + + /// @brief Test for semantic equivalence + bool is_structurally_equivalent_to_impl(const NumericFluentImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const Function& get_function() const; + double get_number() const; +}; + +} + + +namespace std { + // Inject comparison and hash function to make pointers behave appropriately with ordered and unordered datastructures + template<> + struct less + { + bool operator()(const loki::pddl::NumericFluent& left_numeric_fluent, const loki::pddl::NumericFluent& right_numeric_fluent) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::NumericFluentImpl& numeric_fluent) const; + }; +} + +#endif diff --git a/include/loki/problem/pddl/parser.hpp b/include/loki/problem/pddl/parser.hpp new file mode 100644 index 00000000..82e7460e --- /dev/null +++ b/include/loki/problem/pddl/parser.hpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_PROBLEM_PDDL_PARSER_HPP_ +#define LOKI_INCLUDE_LOKI_PROBLEM_PDDL_PARSER_HPP_ + +#include "../../common/pddl/context.hpp" +#include "declarations.hpp" + +#include "../ast/ast.hpp" + + +namespace loki { + +extern pddl::Problem parse(const problem::ast::Problem& problem_node, Context& context, const pddl::Domain& domain); + +} + +#endif diff --git a/include/loki/problem/pddl/problem.hpp b/include/loki/problem/pddl/problem.hpp new file mode 100644 index 00000000..d91aa340 --- /dev/null +++ b/include/loki/problem/pddl/problem.hpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_INCLUDE_LOKI_PROBLEM_PDDL_PROBLEM_HPP_ +#define LOKI_INCLUDE_LOKI_PROBLEM_PDDL_PROBLEM_HPP_ + +#include "declarations.hpp" + +#include "../../common/pddl/base.hpp" + +#include + + +namespace loki { +template +class PersistentFactory; +} + + +namespace loki::pddl { +class ProblemImpl : public Base { +private: + Domain m_domain; + std::string m_name; + Requirements m_requirements; + ObjectList m_objects; + LiteralList m_initial_literals; + NumericFluentList m_numeric_fluents; + Condition m_goal_condition; + std::optional m_optimization_metric; + + template + friend class loki::PersistentFactory; + +public: + ProblemImpl(int identifier, Domain domain, std::string name, Requirements requirements, ObjectList objects, LiteralList initial_literals, NumericFluentList numeric_fluents, Condition goal_condition, std::optional optimization_metric); + + /// @brief Test for semantic equivalence + bool is_structurally_equivalent_to_impl(const ProblemImpl& other) const; + size_t hash_impl() const; + void str_impl(std::ostringstream& out, const FormattingOptions& options) const; + + const Domain& get_domain() const; + const std::string& get_name() const; + const Requirements& get_requirements() const; + const ObjectList& get_objects() const; + const LiteralList& get_initial_literals() const; + const NumericFluentList& numeric_fluents() const; + const Condition& get_goal_condition() const; + const std::optional& get_optimization_metric() const; +}; + +} + + +namespace std { + // Inject comparison and hash function to make pointers behave appropriately with ordered and unordered datastructures + template<> + struct less + { + bool operator()(const loki::pddl::Problem& left_problem, const loki::pddl::Problem& right_problem) const; + }; + + template<> + struct hash + { + std::size_t operator()(const loki::pddl::ProblemImpl& problem) const; + }; +} + +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000..62a80491 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,18 @@ +file(GLOB SRC_FILES + "common/*.cpp" + "common/ast/*.cpp" + "common/pddl/*.cpp" + "common/pddl/parser/*.cpp" + "domain/*.cpp" + "domain/ast/*.cpp" + "domain/pddl/*.cpp" + "domain/pddl/parser/*.cpp" + "problem/*.cpp" + "problem/ast/*.cpp" + "problem/pddl/*.cpp" + "problem/pddl/parser/*.cpp") +add_library(parsers STATIC ${SRC_FILES}) +# target_link_libraries(parsers PRIVATE flatbuffers) + +# Create an alias for simpler reference +add_library(loki::parsers ALIAS parsers) diff --git a/src/common/exceptions.cpp b/src/common/exceptions.cpp new file mode 100644 index 00000000..779850c6 --- /dev/null +++ b/src/common/exceptions.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../include/loki/common/exceptions.hpp" + + +namespace loki { +FileNotExistsError::FileNotExistsError(const std::string& path_to_file) + : std::runtime_error("File does not exist at " + path_to_file) { } + +SyntaxParserError::SyntaxParserError(const std::string& message, const std::string& error_handler_output) + : std::runtime_error(message + "\n" + error_handler_output) { } + +SemanticParserError::SemanticParserError(const std::string& message, const std::string& error_handler_output) + : std::runtime_error(message + "\n" + error_handler_output) { } + +NotImplementedError::NotImplementedError(const std::string& message) + : std::runtime_error(message) { } + +} diff --git a/src/common/filesystem.cpp b/src/common/filesystem.cpp new file mode 100644 index 00000000..17d4f1f6 --- /dev/null +++ b/src/common/filesystem.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../include/loki/common/filesystem.hpp" + +#include "../../include/loki/common/exceptions.hpp" + +#include +#include +#include + + +namespace loki { + +std::string read_file(const fs::path& file_path) { + std::ifstream file(file_path.c_str()); + if (!file.is_open()) { + throw FileNotExistsError(std::string(file_path.c_str())); + } + + std::stringstream buffer; + std::string line; + + while (std::getline(file, line)) { + // Strip comments + size_t commentPos = line.find(';'); + if (commentPos != std::string::npos) { + line = line.substr(0, commentPos); + } + + // Replace tabs with four spaces + size_t tabPos = 0; + while ((tabPos = line.find('\t', tabPos)) != std::string::npos) { + line.replace(tabPos, 1, " "); + tabPos += 4; // Move past the new spaces + } + + buffer << line << '\n'; + } + return buffer.str(); +} + +} \ No newline at end of file diff --git a/src/common/memory.cpp b/src/common/memory.cpp new file mode 100644 index 00000000..0e84a98f --- /dev/null +++ b/src/common/memory.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../include/loki/common/memory.hpp" + + +namespace loki { + +std::tuple process_mem_usage() +{ + using std::ios_base; + using std::ifstream; + using std::string; + + // 'file' stat seems to give the most reliable results + // + ifstream stat_stream("/proc/self/stat",ios_base::in); + + // dummy vars for leading entries in stat that we don't care about + // + string pid, comm, state, ppid, pgrp, session, tty_nr; + string tpgid, flags, minflt, cminflt, majflt, cmajflt; + string utime, stime, cutime, cstime, priority, nice; + string O, itrealvalue, starttime; + + // the two fields we want + // + unsigned long vsize; + long rss; + + stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr + >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt + >> utime >> stime >> cutime >> cstime >> priority >> nice + >> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest + + stat_stream.close(); + + long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages + double vm_usage = vsize / 1024.0; + double resident_set = rss * page_size_kb; + + return std::make_tuple(vm_usage, resident_set); +} + +} \ No newline at end of file diff --git a/src/common/pddl/scope.cpp b/src/common/pddl/scope.cpp new file mode 100644 index 00000000..708f35c9 --- /dev/null +++ b/src/common/pddl/scope.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/common/pddl/scope.hpp" + + +namespace loki { + +Scope::Scope(const Scope* parent_scope) : m_parent_scope(parent_scope) { } + + +ScopeStack::ScopeStack( + const PDDLErrorHandler& error_handler, + const ScopeStack* parent) + : m_error_handler(error_handler) + , m_parent(parent) { } + +void ScopeStack::open_scope() { + m_stack.push_back(m_stack.empty() + ? std::make_unique() + : std::make_unique(m_stack.back().get())); +} + +void ScopeStack::close_scope() { + assert(!m_stack.empty()); + m_stack.pop_back(); +} + +const PDDLErrorHandler& ScopeStack::get_error_handler() const { + return m_error_handler; +} + +const std::deque>& ScopeStack::get_stack() const { + return m_stack; +} + +} \ No newline at end of file diff --git a/src/domain/ast/ast_adapted.hpp b/src/domain/ast/ast_adapted.hpp new file mode 100644 index 00000000..034c7e42 --- /dev/null +++ b/src/domain/ast/ast_adapted.hpp @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_DOMAIN_AST_AST_ADAPTED_HPP_ +#define LOKI_SRC_DOMAIN_AST_AST_ADAPTED_HPP_ + +#include "../../../include/loki/domain/ast/ast.hpp" + +#include +#include + +// We need to tell fusion about our rexpr and rexpr_key_value +// to make them a first-class fusion citizens +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::Name, characters) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::Variable, characters) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::FunctionSymbol, name) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::Predicate, name) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::Number, value) + +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::TypeEither, types) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::TypedListOfNamesRecursively, names, type, typed_list_of_names) + +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::TypedListOfVariablesRecursively, variables, type, typed_list_of_variables) + +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::AtomicFormulaSkeleton, predicate, typed_list_of_variables) + +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::AtomicFunctionSkeletonTotalCost, function_symbol) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::AtomicFunctionSkeletonGeneral, function_symbol, arguments) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::FunctionTypedListOfAtomicFunctionSkeletonsRecursively, atomic_function_skeletons, function_type, function_typed_list_of_atomic_function_skeletons) + +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::AtomicFormulaOfTermsPredicate, predicate, terms) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::AtomicFormulaOfTermsEquality, term_left, term_right) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::Atom, atomic_formula_of_terms) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::NegatedAtom, atomic_formula_of_terms) + +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::FunctionHead, function_symbol, terms) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::FunctionExpressionNumber, number) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::FunctionExpressionBinaryOp, binary_operator, function_expression_left, function_expression_right) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::FunctionExpressionMinus, function_expression) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::FunctionExpressionHead, function_head) + +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::GoalDescriptorAtom, atom) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::GoalDescriptorLiteral, literal) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::GoalDescriptorAnd, goal_descriptors) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::GoalDescriptorOr, goal_descriptors) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::GoalDescriptorNot, goal_descriptor) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::GoalDescriptorImply, goal_descriptor_left, goal_descriptor_right) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::GoalDescriptorExists, typed_list_of_variables, goal_descriptor) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::GoalDescriptorForall, typed_list_of_variables, goal_descriptor) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::GoalDescriptorFunctionComparison, binary_comparator, function_expression_left, function_expression_right) + +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::ConstraintGoalDescriptorAnd, constraint_goal_descriptors) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::ConstraintGoalDescriptorForall, typed_list_of_variables, constraint_goal_descriptor) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::ConstraintGoalDescriptorAtEnd, goal_descriptor) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::ConstraintGoalDescriptorAlways, goal_descriptor) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::ConstraintGoalDescriptorSometime, goal_descriptor) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::ConstraintGoalDescriptorWithin, number, goal_descriptor) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::ConstraintGoalDescriptorAtMostOnce, goal_descriptor) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::ConstraintGoalDescriptorSometimeAfter, goal_descriptor_left, goal_descriptor_right) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::ConstraintGoalDescriptorSometimeBefore, goal_descriptor_left, goal_descriptor_right) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::ConstraintGoalDescriptorAlwaysWithin, number, goal_descriptor_left, goal_descriptor_right) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::ConstraintGoalDescriptorHoldDuring, number_left, number_right, goal_descriptor) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::ConstraintGoalDescriptorHoldAfter, number, goal_descriptor) + +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::PreferenceName, name) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::PreconditionGoalDescriptorSimple, goal_descriptor) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::PreconditionGoalDescriptorAnd, precondition_goal_descriptors) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::PreconditionGoalDescriptorPreference, preference_name, goal_descriptor) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::PreconditionGoalDescriptorForall, typed_list_of_variables, precondition_goal_descriptor) + +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::EffectProductionLiteral, literal) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::EffectProductionNumericFluentTotalCost, assign_operator_increase, function_symbol_total_cost, numeric_term) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::EffectProductionNumericFluentGeneral, assign_operator, function_head, function_expression) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::EffectConditionalForall, typed_list_of_variables, effect) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::EffectConditionalWhen, goal_descriptor, effect) + +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::ActionSymbol, name) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::ActionBody, precondition_goal_descriptor, effect) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::Action, action_symbol, typed_list_of_variables, action_body) + +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::DerivedPredicate, typed_list_of_variables, goal_descriptor) + +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::DomainName, name) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::Requirements, requirements) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::Types, typed_list_of_names) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::Constants, typed_list_of_names) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::Predicates, atomic_formula_skeletons) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::Functions, function_types_list_of_atomic_function_skeletons) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::Constraints, constraint_goal_descriptor) +BOOST_FUSION_ADAPT_STRUCT(loki::domain::ast::Domain, domain_name, requirements, types, constants, predicates, functions, constraints, structures) + + +#endif diff --git a/src/domain/ast/parser.hpp b/src/domain/ast/parser.hpp new file mode 100644 index 00000000..69b267f4 --- /dev/null +++ b/src/domain/ast/parser.hpp @@ -0,0 +1,550 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_DOMAIN_AST_PARSER_HPP_ +#define LOKI_SRC_DOMAIN_AST_PARSER_HPP_ + +#include "../../../include/loki/domain/ast/ast.hpp" + +#include + + +namespace loki::domain { + namespace x3 = boost::spirit::x3; + namespace ascii = boost::spirit::x3::ascii; + + using x3::lit; + using x3::string; + using x3::no_skip; + + using ascii::char_; + using ascii::space; + + /////////////////////////////////////////////////////////////////////////// + // parser public interface for testing + /////////////////////////////////////////////////////////////////////////// + namespace parser { + struct DefineKeywordClass; + struct DomainKeywordClass; + + struct NameClass; + struct VariableClass; + struct NameTotalCostClass; + struct FunctionSymbolTotalCostClass; + struct FunctionSymbolClass; + struct TermClass; + struct NumberClass; + struct PredicateClass; + + struct RequirementStripsClass; + struct RequirementTypingClass; + struct RequirementNegativePreconditionsClass; + struct RequirementDisjunctivePreconditionsClass; + struct RequirementEqualityClass; + struct RequirementExistentialPreconditionsClass; + struct RequirementUniversalPreconditionsClass; + struct RequirementQuantifiedPreconditionsClass; + struct RequirementConditionalEffectsClass; + struct RequirementFluentsClass; + struct RequirementObjectFluentsClass; + struct RequirementNumericFluentsClass; + struct RequirementAdlClass; + struct RequirementDurativeActionsClass; + struct RequirementDerivedPredicatesClass; + struct RequirementTimedInitialLiteralsClass; + struct RequirementPreferencesClass; + struct RequirementConstraintsClass; + struct RequirementActionCostsClass; + struct RequirementClass; + + struct TypeClass; + struct TypeObjectClass; + struct TypeNumberClass; + struct TypeEitherClass; + struct TypedListOfNamesRecursivelyClass; + struct TypedListOfNamesClass; + struct TypedListOfVariablesRecursivelyClass; + struct TypedListOfVariablesClass; + + struct AtomicFormulaSkeletonClass; + + struct AtomicFunctionSkeletonTotalCostClass; + struct AtomicFunctionSkeletonGeneralClass; + struct AtomicFunctionSkeletonClass; + struct FunctionTypedListOfAtomicFunctionSkeletonsRecursivelyClass; + struct FunctionTypedListOfAtomicFunctionSkeletonsClass; + + struct AtomicFormulaOfTermsPredicateClass; + struct AtomicFormulaOfTermsEqualityClass; + struct AtomicFormulaOfTermsClass; + struct AtomClass; + struct NegatedAtomClass; + struct LiteralClass; + + struct MultiOperatorMulClass; + struct MultiOperatorPlusClass; + struct MultiOperatorClass; + struct BinaryOperatorMinusClass; + struct BinaryOperatorDivClass; + struct BinaryOperatorClass; + + struct BinaryComparatorGreaterClass; + struct BinaryComparatorLessClass; + struct BinaryComparatorEqualClass; + struct BinaryComparatorGreaterEqualClass; + struct BinaryComparatorLessEqualClass; + struct BinaryComparatorClass; + + struct FunctionHeadClass; + struct FunctionExpressionClass; + struct FunctionExpressionNumberClass; + struct FunctionExpressionBinaryOpClass; + struct FunctionExpressionMinusClass; + struct FunctionExpressionHeadClass; + + struct GoalDescriptorClass; + struct GoalDescriptorAtomClass; + struct GoalDescriptorLiteralClass; + struct GoalDescriptorAndClass; + struct GoalDescriptorOrClass; + struct GoalDescriptorNotClass; + struct GoalDescriptorImplyClass; + struct GoalDescriptorExistsClass; + struct GoalDescriptorForallClass; + struct GoalDescriptorFunctionComparisonClass; + + struct ConstraintGoalDescriptorClass; + struct ConstraintGoalDescriptorAndClass; + struct ConstraintGoalDescriptorForallClass; + struct ConstraintGoalDescriptorAtEndClass; + struct ConstraintGoalDescriptorAlwaysClass; + struct ConstraintGoalDescriptorSometimeClass; + struct ConstraintGoalDescriptorWithinClass; + struct ConstraintGoalDescriptorAtMostOnceClass; + struct ConstraintGoalDescriptorSometimeAfterClass; + struct ConstraintGoalDescriptorSometimeBeforeClass; + struct ConstraintGoalDescriptorAlwaysWithinClass; + struct ConstraintGoalDescriptorHoldDuringClass; + struct ConstraintGoalDescriptorHoldAfterClass; + + struct PreferenceNameClass; + struct PreconditionGoalDescriptorClass; + struct PreconditionGoalDescriptorSimpleClass; + struct PreconditionGoalDescriptorAndClass; + struct PreconditionGoalDescriptorPreferenceClass; + struct PreconditionGoalDescriptorForallClass; + + struct AssignOperatorAssignClass; + struct AssignOperatorScaleUpClass; + struct AssignOperatorScaleDownClass; + struct AssignOperatorIncreaseClass; + struct AssignOperatorDecreaseClass; + struct AssignOperatorClass; + + struct NumericTermClass; + + struct EffectClass; + struct EffectProductionLiteralClass; + struct EffectProductionNumericFluentTotalCostClass; + struct EffectProductionNumericFluentGeneralClass; + struct EffectProductionClass; + struct EffectConditionalForallClass; + struct EffectConditionalWhenClass; + struct EffectConditionalClass; + struct ActionSymbolClass; + struct ActionBodyClass; + struct ActionClass; + struct DurativeActionClass; // TODO + struct DerivedPredicateClass; + + struct DomainNameClass; + struct RequirementsClass; + struct TypesClass; + struct ConstantsClass; + struct PredicatesClass; + struct FunctionsClass; + struct ConstraintsClass; + struct StructureClass; + + typedef x3::rule define_keyword_type; + typedef x3::rule domain_keyword_type; + + typedef x3::rule name_type; + typedef x3::rule variable_type; + typedef x3::rule name_total_cost_type; + typedef x3::rule function_symbol_total_cost_type; + typedef x3::rule function_symbol_type; + typedef x3::rule term_type; + typedef x3::rule number_type; + typedef x3::rule predicate_type; + + typedef x3::rule requirement_strips_type; + typedef x3::rule requirement_typing_type; + typedef x3::rule requirement_negative_preconditions_type; + typedef x3::rule requirement_disjunctive_preconditions_type; + typedef x3::rule requirement_equality_type; + typedef x3::rule requirement_existential_preconditions_type; + typedef x3::rule requirement_universal_preconditions_type; + typedef x3::rule requirement_quantified_preconditions_type; + typedef x3::rule requirement_conditional_effects_type; + typedef x3::rule requirement_fluents_type; + typedef x3::rule requirement_object_fluents_type; + typedef x3::rule requirement_numeric_fluents_type; + typedef x3::rule requirement_adl_type; + typedef x3::rule requirement_durative_actions_type; + typedef x3::rule requirement_derived_predicates_type; + typedef x3::rule requirement_timed_initial_literals_type; + typedef x3::rule requirement_preferences_type; + typedef x3::rule requirement_constraints_type; + typedef x3::rule requirement_action_costs_type; + typedef x3::rule requirement_type; + + typedef x3::rule type_type; + typedef x3::rule type_object_type; + typedef x3::rule type_number_type; + typedef x3::rule type_either_type; + typedef x3::rule typed_list_of_names_recursively_type; + typedef x3::rule typed_list_of_names_type; + typedef x3::rule typed_list_of_variables_recursively_type; + typedef x3::rule typed_list_of_variables_type; + + typedef x3::rule atomic_formula_skeleton_type; + + typedef x3::rule atomic_function_skeleton_total_cost_type; + typedef x3::rule atomic_function_skeleton_general_type; + typedef x3::rule atomic_function_skeleton_type; + typedef x3::rule function_typed_list_of_atomic_function_skeletons_recursively_type; + typedef x3::rule function_typed_list_of_atomic_function_skeletons_type; + + typedef x3::rule atomic_formula_of_terms_predicate_type; + typedef x3::rule atomic_formula_of_terms_equality_type; + typedef x3::rule atomic_formula_of_terms_type; + typedef x3::rule atom_type; + typedef x3::rule negated_atom_type; + typedef x3::rule literal_type; + + typedef x3::rule multi_operator_mul_type; + typedef x3::rule multi_operator_plus_type; + typedef x3::rule multi_operator_type; + typedef x3::rule binary_operator_minus_type; + typedef x3::rule binary_operator_div_type; + typedef x3::rule binary_operator_type; + + typedef x3::rule binary_comparator_greater_type; + typedef x3::rule binary_comparator_less_type; + typedef x3::rule binary_comparator_equal_type; + typedef x3::rule binary_comparator_greater_equal_type; + typedef x3::rule binary_comparator_less_equal_type; + typedef x3::rule binary_comparator_type; + + typedef x3::rule function_expression_type; + typedef x3::rule function_head_type; + typedef x3::rule function_expression_number_type; + typedef x3::rule function_expression_binary_op_type; + typedef x3::rule function_expression_minus_type; + typedef x3::rule function_expression_head_type; + + typedef x3::rule goal_descriptor_type; + typedef x3::rule goal_descriptor_atom_type; + typedef x3::rule goal_descriptor_literal_type; + typedef x3::rule goal_descriptor_and_type; + typedef x3::rule goal_descriptor_or_type; + typedef x3::rule goal_descriptor_not_type; + typedef x3::rule goal_descriptor_imply_type; + typedef x3::rule goal_descriptor_exists_type; + typedef x3::rule goal_descriptor_forall_type; + typedef x3::rule goal_descriptor_function_comparison_type; + + typedef x3::rule constraint_goal_descriptor_type; + typedef x3::rule constraint_goal_descriptor_and_type; + typedef x3::rule constraint_goal_descriptor_forall_type; + typedef x3::rule constraint_goal_descriptor_at_end_type; + typedef x3::rule constraint_goal_descriptor_always_type; + typedef x3::rule constraint_goal_descriptor_sometime_type; + typedef x3::rule constraint_goal_descriptor_within_type; + typedef x3::rule constraint_goal_descriptor_at_most_once_type; + typedef x3::rule constraint_goal_descriptor_sometime_after_type; + typedef x3::rule constraint_goal_descriptor_sometime_before_type; + typedef x3::rule constraint_goal_descriptor_always_within_type; + typedef x3::rule constraint_goal_descriptor_hold_during_type; + typedef x3::rule constraint_goal_descriptor_hold_after_type; + + typedef x3::rule precondition_goal_descriptor_type; + typedef x3::rule preference_name_type; + typedef x3::rule precondition_goal_descriptor_simple_type; + typedef x3::rule precondition_goal_descriptor_and_type; + typedef x3::rule precondition_goal_descriptor_preference_type; + typedef x3::rule precondition_goal_descriptor_forall_type; + + typedef x3::rule assign_operator_assign_type; + typedef x3::rule assign_operator_scale_up_type; + typedef x3::rule assign_operator_scale_down_type; + typedef x3::rule assign_operator_increase_type; + typedef x3::rule assign_operator_decrease_type; + typedef x3::rule assign_operator_type; + + typedef x3::rule numeric_term_type; + + typedef x3::rule effect_type; + typedef x3::rule effect_production_literal_type; + typedef x3::rule effect_production_numeric_fluent_total_cost_type; + typedef x3::rule effect_production_numeric_fluent_general_type; + typedef x3::rule effect_production_type; + typedef x3::rule effect_conditional_forall_type; + typedef x3::rule effect_conditional_when_type; + typedef x3::rule effect_conditional_type; + typedef x3::rule action_symbol_type; + typedef x3::rule action_body_type; + typedef x3::rule action_type; + + typedef x3::rule derived_predicate_type; + + typedef x3::rule domain_name_type; + typedef x3::rule requirements_type; + typedef x3::rule types_type; + typedef x3::rule constants_type; + typedef x3::rule predicates_type; + typedef x3::rule functions_type; + typedef x3::rule constraints_type; + typedef x3::rule structure_type; + + BOOST_SPIRIT_DECLARE(define_keyword_type, domain_keyword_type) + + BOOST_SPIRIT_DECLARE(name_type, variable_type, name_total_cost_type, function_symbol_total_cost_type, function_symbol_type, term_type, number_type, predicate_type) + + BOOST_SPIRIT_DECLARE( + requirement_strips_type, requirement_typing_type, requirement_negative_preconditions_type, requirement_disjunctive_preconditions_type, + requirement_equality_type, requirement_existential_preconditions_type, requirement_universal_preconditions_type, + requirement_quantified_preconditions_type, requirement_conditional_effects_type, requirement_fluents_type, + requirement_object_fluents_type, requirement_numeric_fluents_type, requirement_adl_type, requirement_durative_actions_type, + requirement_derived_predicates_type, requirement_timed_initial_literals_type, requirement_preferences_type, + requirement_constraints_type, requirement_action_costs_type, requirement_type) + + BOOST_SPIRIT_DECLARE( + type_type, type_object_type, type_number_type, type_either_type, + typed_list_of_names_recursively_type, typed_list_of_names_type, + typed_list_of_variables_recursively_type, typed_list_of_variables_type) + + BOOST_SPIRIT_DECLARE(atomic_formula_skeleton_type) + + BOOST_SPIRIT_DECLARE(atomic_function_skeleton_total_cost_type, atomic_function_skeleton_general_type, atomic_function_skeleton_type, + function_typed_list_of_atomic_function_skeletons_recursively_type, function_typed_list_of_atomic_function_skeletons_type) + + BOOST_SPIRIT_DECLARE(atomic_formula_of_terms_type, atom_type, negated_atom_type, literal_type) + + BOOST_SPIRIT_DECLARE(multi_operator_mul_type, multi_operator_plus_type, multi_operator_type, + binary_operator_minus_type, binary_operator_div_type, binary_operator_type) + + BOOST_SPIRIT_DECLARE(binary_comparator_greater_type, binary_comparator_less_type, + binary_comparator_equal_type, binary_comparator_greater_equal_type, + binary_comparator_less_equal_type, binary_comparator_type) + + BOOST_SPIRIT_DECLARE(function_expression_type, function_head_type, function_expression_number_type, + function_expression_number_type, function_expression_binary_op_type, + function_expression_minus_type, function_expression_head_type) + + BOOST_SPIRIT_DECLARE(goal_descriptor_type, goal_descriptor_atom_type, goal_descriptor_literal_type, + goal_descriptor_and_type, goal_descriptor_or_type, goal_descriptor_not_type, + goal_descriptor_imply_type, goal_descriptor_exists_type, goal_descriptor_forall_type, + goal_descriptor_function_comparison_type) + + BOOST_SPIRIT_DECLARE(constraint_goal_descriptor_type, constraint_goal_descriptor_and_type, + constraint_goal_descriptor_forall_type, constraint_goal_descriptor_at_end_type, + constraint_goal_descriptor_always_type, constraint_goal_descriptor_sometime_type, + constraint_goal_descriptor_within_type, constraint_goal_descriptor_at_most_once_type, + constraint_goal_descriptor_sometime_after_type, constraint_goal_descriptor_sometime_before_type, + constraint_goal_descriptor_always_within_type, constraint_goal_descriptor_hold_during_type, + constraint_goal_descriptor_hold_after_type) + + BOOST_SPIRIT_DECLARE(precondition_goal_descriptor_type, preference_name_type, + precondition_goal_descriptor_simple_type, precondition_goal_descriptor_and_type, + precondition_goal_descriptor_preference_type, precondition_goal_descriptor_forall_type) + + BOOST_SPIRIT_DECLARE(assign_operator_assign_type, assign_operator_scale_up_type, assign_operator_scale_down_type, + assign_operator_increase_type, assign_operator_decrease_type, assign_operator_type) + + BOOST_SPIRIT_DECLARE(numeric_term_type) + + BOOST_SPIRIT_DECLARE(effect_type, effect_production_literal_type, + effect_production_numeric_fluent_total_cost_type, effect_production_numeric_fluent_general_type, + effect_production_type, effect_conditional_forall_type, + effect_conditional_when_type, effect_conditional_type, action_symbol_type, action_body_type, action_type, + derived_predicate_type) + + + BOOST_SPIRIT_DECLARE(domain_name_type, requirements_type, + types_type, constants_type, predicates_type, functions_type, constraints_type, structure_type) + } + + inline auto separator() { + return (ascii::space | lit('\n') | lit('(') | lit(')')); // TODO: is ) correct? + } + + /// @brief Matches a keyword + inline auto keyword_lit(const std::string& keyword) { + return lit(keyword) >> no_skip[&separator()]; + } + + /// @brief Synthesizes a keyword string + inline auto keyword_string(const std::string& keyword) { + return string(keyword) >> no_skip[&separator()]; + } + + parser::define_keyword_type const& define_keyword(); + parser::domain_keyword_type const& domain_keyword(); + + parser::name_type const& name(); + parser::variable_type const& variable(); + parser::number_type const& number(); + parser::name_total_cost_type const& name_total_cost(); + parser::function_symbol_total_cost_type const& function_symbol_total_cost(); + parser::function_symbol_type const& function_symbol(); + parser::term_type const& term(); + parser::predicate_type const& predicate(); + + parser::requirement_strips_type const& requirement_strips(); + parser::requirement_typing_type const& requirement_typing(); + parser::requirement_negative_preconditions_type const& requirement_negative_preconditions(); + parser::requirement_disjunctive_preconditions_type const& requirement_disjunctive_preconditions(); + parser::requirement_equality_type const& requirement_equality(); + parser::requirement_existential_preconditions_type const& requirement_existential_preconditions(); + parser::requirement_universal_preconditions_type const& requirement_universal_preconditions(); + parser::requirement_quantified_preconditions_type const& requirement_quantified_preconditions(); + parser::requirement_conditional_effects_type const& requirement_conditional_effects(); + parser::requirement_fluents_type const& requirement_fluents(); + parser::requirement_object_fluents_type const& requirement_object_fluents(); + parser::requirement_numeric_fluents_type const& requirement_numeric_fluents(); + parser::requirement_adl_type const& requirement_adl(); + parser::requirement_durative_actions_type const& requirement_durative_actions(); + parser::requirement_derived_predicates_type const& requirement_derived_predicates(); + parser::requirement_timed_initial_literals_type const& requirement_timed_initial_literals(); + parser::requirement_preferences_type const& requirement_preferences(); + parser::requirement_constraints_type const& requirement_constraints(); + parser::requirement_action_costs_type const& requirement_action_costs(); + parser::requirement_type const& requirement(); + + parser::type_type const& type(); + parser::type_object_type const& type_object(); + parser::type_number_type const& type_number(); + parser::type_either_type const& type_either(); + parser::typed_list_of_names_recursively_type const& typed_list_of_names_recursively(); + parser::typed_list_of_names_type const& typed_list_of_names(); + parser::typed_list_of_variables_recursively_type const& typed_list_of_variables_recursively(); + parser::typed_list_of_variables_type const& typed_list_of_variables(); + + parser::atomic_formula_skeleton_type const& atomic_formula_skeleton(); + + parser::multi_operator_mul_type const& multi_operator_mul(); + parser::multi_operator_plus_type const& multi_operator_plus(); + parser::multi_operator_type const& multi_operator(); + parser::binary_operator_minus_type const& binary_operator_minus(); + parser::binary_operator_div_type const& binary_operator_div(); + parser::binary_operator_type const& binary_operator(); + + parser::binary_comparator_greater_type const& binary_comparator_greater(); + parser::binary_comparator_less_type const& binary_comparator_less(); + parser::binary_comparator_equal_type const& binary_comparator_equal(); + parser::binary_comparator_greater_equal_type const& binary_comparator_greater_equal(); + parser::binary_comparator_less_equal_type const& binary_comparator_less_equal(); + parser::binary_comparator_type const& binary_comparator(); + + parser::atomic_function_skeleton_total_cost_type const& atomic_function_skeleton_total_cost(); + parser::atomic_function_skeleton_general_type const& atomic_function_skeleton_general(); + parser::atomic_function_skeleton_type const& atomic_function_skeleton(); + parser::function_typed_list_of_atomic_function_skeletons_recursively_type const& function_typed_list_of_atomic_function_skeletons_recursively(); + parser::function_typed_list_of_atomic_function_skeletons_type const& function_typed_list_of_atomic_function_skeletons(); + + parser::atomic_formula_of_terms_predicate_type const& atomic_formula_of_terms_predicate(); + parser::atomic_formula_of_terms_equality_type const& atomic_formula_of_terms_equality(); + parser::atomic_formula_of_terms_type const& atomic_formula_of_terms(); + parser::atom_type const& atom(); + parser::negated_atom_type const& negated_atom(); + parser::literal_type const& literal(); + + parser::function_expression_type const& function_expression(); + parser::function_head_type const& function_head(); + parser::function_expression_number_type const& function_expression_number(); + parser::function_expression_binary_op_type const& function_expression_binary_op(); + parser::function_expression_minus_type const& function_expression_minus(); + parser::function_expression_head_type const& function_expression_head(); + + parser::goal_descriptor_type const& goal_descriptor(); + parser::goal_descriptor_atom_type const& goal_descriptor_atom(); + parser::goal_descriptor_literal_type const& goal_descriptor_literal(); + parser::goal_descriptor_and_type const& goal_descriptor_and(); + parser::goal_descriptor_or_type const& goal_descriptor_or(); + parser::goal_descriptor_not_type const& goal_descriptor_not(); + parser::goal_descriptor_imply_type const& goal_descriptor_imply(); + parser::goal_descriptor_exists_type const& goal_descriptor_exists(); + parser::goal_descriptor_forall_type const& goal_descriptor_forall(); + parser::goal_descriptor_function_comparison_type const& goal_descriptor_function_comparison(); + + parser::constraint_goal_descriptor_type const& constraint_goal_descriptor(); + parser::constraint_goal_descriptor_and_type const& constraint_goal_descriptor_and(); + parser::constraint_goal_descriptor_forall_type const& constraint_goal_descriptor_forall(); + parser::constraint_goal_descriptor_at_end_type const& constraint_goal_descriptor_at_end(); + parser::constraint_goal_descriptor_always_type const& constraint_goal_descriptor_always(); + parser::constraint_goal_descriptor_sometime_type const& constraint_goal_descriptor_sometime(); + parser::constraint_goal_descriptor_within_type const& constraint_goal_descriptor_within(); + parser::constraint_goal_descriptor_at_most_once_type const& constraint_goal_descriptor_at_most_once(); + parser::constraint_goal_descriptor_sometime_after_type const& constraint_goal_descriptor_sometime_after(); + parser::constraint_goal_descriptor_sometime_before_type const& constraint_goal_descriptor_sometime_before(); + parser::constraint_goal_descriptor_always_within_type const& constraint_goal_descriptor_always_within(); + parser::constraint_goal_descriptor_hold_during_type const& constraint_goal_descriptor_hold_during(); + parser::constraint_goal_descriptor_hold_after_type const& constraint_goal_descriptor_hold_after(); + + parser::precondition_goal_descriptor_type const& precondition_goal_descriptor(); + parser::preference_name_type const& preference_name(); + parser::precondition_goal_descriptor_simple_type const& precondition_goal_descriptor_simple(); + parser::precondition_goal_descriptor_and_type const& precondition_goal_descriptor_and(); + parser::precondition_goal_descriptor_preference_type const& precondition_goal_descriptor_preference(); + parser::precondition_goal_descriptor_forall_type const& precondition_goal_descriptor_forall(); + + parser::assign_operator_assign_type const& assign_operator_assign(); + parser::assign_operator_scale_up_type const& assign_operator_scale_up(); + parser::assign_operator_scale_down_type const& assign_operator_scale_down(); + parser::assign_operator_increase_type const& assign_operator_increase(); + parser::assign_operator_decrease_type const& assign_operator_decrease(); + parser::assign_operator_type const& assign_operator(); + + parser::numeric_term_type const& numeric_term(); + + parser::effect_type const& effect(); + parser::effect_production_literal_type const& effect_production_literal(); + parser::effect_production_numeric_fluent_total_cost_type const& effect_production_numeric_fluent_total_cost(); + parser::effect_production_numeric_fluent_general_type const& effect_production_numeric_fluent_general(); + parser::effect_production_type const& effect_production(); + parser::effect_conditional_forall_type const& effect_conditional_forall(); + parser::effect_conditional_when_type const& effect_conditional_when(); + parser::effect_conditional_type const& effect_conditional(); + parser::action_symbol_type const& action_symbol(); + parser::action_body_type const& action_body(); + parser::action_type const& action(); + parser::derived_predicate_type const& derived_predicate(); + + parser::domain_name_type const& domain_name(); + parser::requirements_type const& requirements(); + parser::types_type const& types(); + parser::constants_type const& constants(); + parser::predicates_type const& predicates(); + parser::functions_type const& functions(); + parser::constraints_type const& constraints(); + parser::structure_type const& structure(); + +} + +#endif diff --git a/src/domain/ast/parser_def.hpp b/src/domain/ast/parser_def.hpp new file mode 100644 index 00000000..d402af26 --- /dev/null +++ b/src/domain/ast/parser_def.hpp @@ -0,0 +1,976 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_DOMAIN_AST_PARSER_DEF_HPP_ +#define LOKI_SRC_DOMAIN_AST_PARSER_DEF_HPP_ + +#include "ast_adapted.hpp" +#include "parser.hpp" + +#include "../../../include/loki/common/ast/parser_wrapper.hpp" +#include "../../../include/loki/domain/ast/ast.hpp" +#include "../../../include/loki/domain/ast/error_handler.hpp" +#include "../../../include/loki/domain/ast/parser.hpp" + +#include +#include + + +namespace loki::domain::parser { + namespace x3 = boost::spirit::x3; + namespace ascii = boost::spirit::x3::ascii; + + using x3::lit; + using x3::string; + using x3::lexeme; + using x3::eps; + using x3::int_; + using x3::double_; + using x3::no_skip; + using x3::raw; + + using ascii::alpha; + using ascii::alnum; + using ascii::char_; + using ascii::space; + + /////////////////////////////////////////////////////////////////////////// + // Rule IDs + /////////////////////////////////////////////////////////////////////////// + + + /////////////////////////////////////////////////////////////////////////// + // Rules + /////////////////////////////////////////////////////////////////////////// + + define_keyword_type const define_keyword = "define"; + domain_keyword_type const domain_keyword = "domain"; + + name_type const name = "name"; + variable_type const variable = "variable"; + name_total_cost_type const name_total_cost = "name_total_cost"; + function_symbol_total_cost_type const function_symbol_total_cost = "function_symbol_total_cost"; + function_symbol_type const function_symbol = "function_symbol"; + term_type const term = "term"; + number_type const number = "number"; + predicate_type const predicate = "predicate"; + + requirement_strips_type const requirement_strips = "requirement_strips"; + requirement_typing_type const requirement_typing = "requirement_typing"; + requirement_negative_preconditions_type const requirement_negative_preconditions = "requirement_negative_preconditions"; + requirement_disjunctive_preconditions_type const requirement_disjunctive_preconditions = "requirement_disjunctive_preconditions"; + requirement_equality_type const requirement_equality = "requirement_equality"; + requirement_existential_preconditions_type const requirement_existential_preconditions = "requirement_existential_preconditions"; + requirement_universal_preconditions_type const requirement_universal_preconditions = "requirement_universal_preconditions"; + requirement_quantified_preconditions_type const requirement_quantified_preconditions = "requirement_quantified_preconditions"; + requirement_conditional_effects_type const requirement_conditional_effects = "requirement_conditional_effects"; + requirement_fluents_type const requirement_fluents = "requirement_fluents"; + requirement_object_fluents_type const requirement_object_fluents = "requirement_object_fluents"; + requirement_numeric_fluents_type const requirement_numeric_fluents = "requirement_numeric_fluents"; + requirement_adl_type const requirement_adl = "requirement_adl"; + requirement_durative_actions_type const requirement_durative_actions = "requirement_durative_actions"; + requirement_derived_predicates_type const requirement_derived_predicates = "requirement_derived_predicates"; + requirement_timed_initial_literals_type const requirement_timed_initial_literals = "requirement_timed_initial_literals"; + requirement_preferences_type const requirement_preferences = "requirement_preferences"; + requirement_constraints_type const requirement_constraints = "requirement_constraints"; + requirement_action_costs_type const requirement_action_costs = "requirement_action_costs"; + requirement_type const requirement = "requirement"; + + type_type const type = "type"; + type_object_type const type_object = "type_object"; + type_number_type const type_number = "type_number"; + type_either_type const type_either = "type_either"; + typed_list_of_names_recursively_type const typed_list_of_names_recursively = "typed_list_of_names_recursively"; + typed_list_of_names_type const typed_list_of_names = "typed_list_of_names"; + typed_list_of_variables_recursively_type const typed_list_of_variables_recursively = "typed_list_of_variables_recursively"; + typed_list_of_variables_type const typed_list_of_variables = "typed_list_of_variables"; + + atomic_formula_skeleton_type const atomic_formula_skeleton = "atomic_formula_skeleton"; + + atomic_function_skeleton_total_cost_type const atomic_function_skeleton_total_cost = "atomic_function_skeleton_total_cost"; + atomic_function_skeleton_general_type const atomic_function_skeleton_general = "atomic_function_skeleton_general"; + atomic_function_skeleton_type const atomic_function_skeleton = "atomic_function_skeleton"; + function_typed_list_of_atomic_function_skeletons_recursively_type const function_typed_list_of_atomic_function_skeletons_recursively = "function_typed_list_of_atomic_function_skeletons_recursively"; + function_typed_list_of_atomic_function_skeletons_type const function_typed_list_of_atomic_function_skeletons = "function_typed_list_of_atomic_function_skeletons"; + + atomic_formula_of_terms_predicate_type const atomic_formula_of_terms_predicate = "atomic_formula_of_terms_predicate"; + atomic_formula_of_terms_equality_type const atomic_formula_of_terms_equality = "atomic_formula_of_terms_equality"; + atomic_formula_of_terms_type const atomic_formula_of_terms = "atomic_formula_of_terms"; + atom_type const atom = "atom"; + negated_atom_type const negated_atom = "negated_atom"; + literal_type const literal = "literal"; + + multi_operator_mul_type const multi_operator_mul = "multi_operator_mul"; + multi_operator_plus_type const multi_operator_plus = "multi_operator_plus"; + multi_operator_type const multi_operator = "multi_operator"; + binary_operator_minus_type const binary_operator_minus = "binary_operator_minus"; + binary_operator_div_type const binary_operator_div = "binary_operator_div"; + binary_operator_type const binary_operator = "binary_operator"; + + binary_comparator_greater_type const binary_comparator_greater = "binary_comparator_greater"; + binary_comparator_less_type const binary_comparator_less = "binary_comparator_less"; + binary_comparator_equal_type const binary_comparator_equal = "binary_comparator_equal"; + binary_comparator_greater_equal_type const binary_comparator_greater_equal = "binary_comparator_greater_equal"; + binary_comparator_less_equal_type const binary_comparator_less_equal = "binary_comparator_less_equal"; + binary_comparator_type const binary_comparator = "binary_comparator"; + + function_expression_type const function_expression = "function_expression"; + function_head_type const function_head = "function_head"; + function_expression_number_type const function_expression_number = "function_expression_number"; + function_expression_binary_op_type const function_expression_binary_op = "function_expression_binary_op"; + function_expression_minus_type const function_expression_minus = "function_expression_minus"; + function_expression_head_type const function_expression_head = "function_expression_head"; + + goal_descriptor_type const goal_descriptor = "goal_descriptor"; + goal_descriptor_atom_type const goal_descriptor_atom = "goal_descriptor_atom"; + goal_descriptor_literal_type const goal_descriptor_literal = "goal_descriptor_literal"; + goal_descriptor_and_type const goal_descriptor_and = "goal_descriptor_and"; + goal_descriptor_or_type const goal_descriptor_or = "goal_descriptor_or"; + goal_descriptor_not_type const goal_descriptor_not = "goal_descriptor_not"; + goal_descriptor_imply_type const goal_descriptor_imply = "goal_descriptor_imply"; + goal_descriptor_exists_type const goal_descriptor_exists = "goal_descriptor_exists"; + goal_descriptor_forall_type const goal_descriptor_forall = "goal_descriptor_forall"; + goal_descriptor_function_comparison_type const goal_descriptor_function_comparison = "goal_descriptor_function_comparison"; + + constraint_goal_descriptor_type const constraint_goal_descriptor = "constraint_goal_descriptor"; + constraint_goal_descriptor_and_type const constraint_goal_descriptor_and = "constraint_goal_descriptor_and"; + constraint_goal_descriptor_forall_type const constraint_goal_descriptor_forall = "constraint_goal_descriptor_forall"; + constraint_goal_descriptor_at_end_type const constraint_goal_descriptor_at_end = "constraint_goal_descriptor_at_end"; + constraint_goal_descriptor_always_type const constraint_goal_descriptor_always = "constraint_goal_descriptor_always"; + constraint_goal_descriptor_sometime_type const constraint_goal_descriptor_sometime = "constraint_goal_descriptor_sometime"; + constraint_goal_descriptor_within_type const constraint_goal_descriptor_within = "constraint_goal_descriptor_within"; + constraint_goal_descriptor_at_most_once_type const constraint_goal_descriptor_at_most_once = "constraint_goal_descriptor_at_most_once"; + constraint_goal_descriptor_sometime_after_type const constraint_goal_descriptor_sometime_after = "constraint_goal_descriptor_sometime_after"; + constraint_goal_descriptor_sometime_before_type const constraint_goal_descriptor_sometime_before = "constraint_goal_descriptor_sometime_before"; + constraint_goal_descriptor_always_within_type const constraint_goal_descriptor_always_within = "constraint_goal_descriptor_always_within"; + constraint_goal_descriptor_hold_during_type const constraint_goal_descriptor_hold_during = "constraint_goal_descriptor_hold_during"; + constraint_goal_descriptor_hold_after_type const constraint_goal_descriptor_hold_after = "constraint_goal_descriptor_hold_after"; + + precondition_goal_descriptor_type const precondition_goal_descriptor = "precondition_goal_descriptor"; + preference_name_type const preference_name = "preference_name"; + precondition_goal_descriptor_simple_type const precondition_goal_descriptor_simple = "precondition_goal_descriptor_simple"; + precondition_goal_descriptor_and_type const precondition_goal_descriptor_and = "precondition_goal_descriptor_and"; + precondition_goal_descriptor_preference_type const precondition_goal_descriptor_preference = "precondition_goal_descriptor_preference"; + precondition_goal_descriptor_forall_type const precondition_goal_descriptor_forall = "precondition_goal_descriptor_forall"; + + assign_operator_assign_type const assign_operator_assign = "assign_operator_assign"; + assign_operator_scale_up_type const assign_operator_scale_up = "assign_operator_scale_up"; + assign_operator_scale_down_type const assign_operator_scale_down = "assign_operator_scale_down"; + assign_operator_increase_type const assign_operator_increase = "assign_operator_increase"; + assign_operator_decrease_type const assign_operator_decrease = "assign_operator_decrease"; + assign_operator_type const assign_operator = "assign_operator"; + + numeric_term_type const numeric_term = "numeric_term"; + + effect_type const effect = "effect"; + effect_production_literal_type const effect_production_literal = "effect_production_literal"; + effect_production_numeric_fluent_total_cost_type const effect_production_numeric_fluent_total_cost = "effect_production_numeric_fluent_total_cost"; + effect_production_numeric_fluent_general_type const effect_production_numeric_fluent_general = "effect_production_numeric_fluent_general"; + effect_production_type const effect_production = "effect_production"; + effect_conditional_forall_type const effect_conditional_forall = "effect_conditional_forall"; + effect_conditional_when_type const effect_conditional_when = "effect_conditional_when"; + effect_conditional_type const effect_conditional = "effect_conditional"; + action_symbol_type const action_symbol = "action_symbol"; + action_body_type const action_body = "action_body"; + action_type const action = "action"; + derived_predicate_type const derived_predicate = "derived_predicate"; + + domain_name_type const domain_name = "domain_name"; + requirements_type const requirements = "requirements"; + types_type const types = "types"; + constants_type const constants = "constants"; + predicates_type const predicates = "predicates"; + functions_type const functions = "functions"; + constraints_type const constraints = "constraints"; + structure_type const structure = "structure"; + domain_type const domain = "domain"; + + /////////////////////////////////////////////////////////////////////////// + // Grammar + /////////////////////////////////////////////////////////////////////////// + + const auto name_def = raw[lexeme[alpha >> *(alnum | char_('-') | char_('_'))]]; + const auto variable_def = raw[lexeme[char_('?') > name]]; + const auto name_total_cost_def = keyword_string("total-cost"); + const auto function_symbol_total_cost_def = name_total_cost; + const auto function_symbol_def = name; + const auto term_def = name | variable; + const auto number_def = double_; + const auto predicate_def = name; + + const auto requirement_strips_def = keyword_lit(":strips") > x3::attr(ast::RequirementStrips{}); + const auto requirement_typing_def = keyword_lit(":typing") > x3::attr(ast::RequirementTyping{}); + const auto requirement_negative_preconditions_def = keyword_lit(":negative-preconditions") > x3::attr(ast::RequirementNegativePreconditions{}); + const auto requirement_disjunctive_preconditions_def = keyword_lit(":disjunctive-preconditions") > x3::attr(ast::RequirementDisjunctivePreconditions{}); + const auto requirement_equality_def = keyword_lit(":equality") > x3::attr(ast::RequirementEquality{}); + const auto requirement_existential_preconditions_def = keyword_lit(":existential-preconditions") > x3::attr(ast::RequirementExistentialPreconditions{}); + const auto requirement_universal_preconditions_def = keyword_lit(":universal-preconditions") > x3::attr(ast::RequirementUniversalPreconditions{}); + const auto requirement_quantified_preconditions_def = keyword_lit(":quantified-preconditions") > x3::attr(ast::RequirementQuantifiedPreconditions{}); + const auto requirement_conditional_effects_def = keyword_lit(":conditional-effects") > x3::attr(ast::RequirementConditionalEffects{}); + const auto requirement_fluents_def = keyword_lit(":fluents") >> x3::attr(ast::RequirementFluents{}); + const auto requirement_object_fluents_def = keyword_lit(":object-fluents") > x3::attr(ast::RequirementObjectFluents{}); + const auto requirement_numeric_fluents_def = keyword_lit(":numeric-fluents") > x3::attr(ast::RequirementNumericFluents{}); + const auto requirement_adl_def = keyword_lit(":adl") >> x3::attr(ast::RequirementAdl{}); + const auto requirement_durative_actions_def = keyword_lit(":durative-actions") > x3::attr(ast::RequirementDurativeActions{}); + const auto requirement_derived_predicates_def = keyword_lit(":derived-predicates") > x3::attr(ast::RequirementDerivedPredicates{}); + const auto requirement_timed_initial_literals_def = keyword_lit(":timed-initial-literals") > x3::attr(ast::RequirementTimedInitialLiterals{}); + const auto requirement_preferences_def = keyword_lit(":preferences") > x3::attr(ast::RequirementPreferences{}); + const auto requirement_constraints_def = keyword_lit(":constraints") > x3::attr(ast::RequirementConstraints{}); + const auto requirement_action_costs_def = keyword_lit(":action-costs") > x3::attr(ast::RequirementActionCosts{}); + const auto requirement_def = requirement_strips | requirement_typing | requirement_negative_preconditions + | requirement_disjunctive_preconditions | requirement_equality | requirement_existential_preconditions + | requirement_universal_preconditions | requirement_quantified_preconditions | requirement_conditional_effects + | requirement_fluents | requirement_object_fluents | requirement_numeric_fluents | requirement_adl + | requirement_durative_actions | requirement_derived_predicates | requirement_timed_initial_literals + | requirement_preferences | requirement_constraints | requirement_action_costs; + + const auto type_def = type_object | type_number | type_either | name; + const auto type_object_def = keyword_lit("object") > x3::attr(ast::TypeObject{}); + const auto type_number_def = keyword_lit("number") > x3::attr(ast::TypeNumber{}); + const auto type_either_def = (lit('(') >> keyword_lit("either") > +type) > lit(')'); + const auto typed_list_of_names_recursively_def = (+name >> lit('-')) > type > typed_list_of_names; + const auto typed_list_of_names_def = typed_list_of_names_recursively | *name; + const auto typed_list_of_variables_recursively_def = (+variable >> lit('-')) > type > typed_list_of_variables; + const auto typed_list_of_variables_def = typed_list_of_variables_recursively | *variable; + + const auto atomic_formula_skeleton_def = lit('(') > predicate > typed_list_of_variables > lit(')'); + + const auto atomic_function_skeleton_total_cost_def = lit('(') >> function_symbol_total_cost > lit(')'); + const auto atomic_function_skeleton_general_def = lit('(') > function_symbol > typed_list_of_variables > lit(')'); + const auto atomic_function_skeleton_def = atomic_function_skeleton_total_cost | atomic_function_skeleton_general; + const auto function_typed_list_of_atomic_function_skeletons_recursively_def = (+atomic_function_skeleton >> lit('-')) > type_number > -function_typed_list_of_atomic_function_skeletons; + const auto function_typed_list_of_atomic_function_skeletons_def = function_typed_list_of_atomic_function_skeletons_recursively | +atomic_function_skeleton; + + const auto atomic_formula_of_terms_predicate_def = (lit('(') >> predicate) > *term > lit(')'); + const auto atomic_formula_of_terms_equality_def = (lit('(') >> lit('=')) >> term > term > lit(')'); + const auto atomic_formula_of_terms_def = atomic_formula_of_terms_equality | atomic_formula_of_terms_predicate; + const auto atom_def = atomic_formula_of_terms; + const auto negated_atom_def = (lit('(') >> keyword_lit("not")) > atomic_formula_of_terms > lit(')'); + const auto literal_def = negated_atom | atom; + + const auto multi_operator_mul_def = lit('*') > x3::attr(ast::MultiOperatorMul{}); + const auto multi_operator_plus_def = lit('+') > x3::attr(ast::MultiOperatorPlus{}); + const auto multi_operator_def = multi_operator_mul | multi_operator_plus; + const auto binary_operator_minus_def = lit('-') > x3::attr(ast::BinaryOperatorMinus{}); + const auto binary_operator_div_def = lit('/') > x3::attr(ast::BinaryOperatorDiv{}); + const auto binary_operator_def = binary_operator_minus | binary_operator_div | multi_operator; + + const auto binary_comparator_greater_def = lit('>') > x3::attr(ast::BinaryComparatorGreater{}); + const auto binary_comparator_less_def = lit('<') > x3::attr(ast::BinaryComparatorLess{}); + const auto binary_comparator_equal_def = lit('=') > x3::attr(ast::BinaryComparatorEqual{}); + const auto binary_comparator_greater_equal_def = lit(">=") > x3::attr(ast::BinaryComparatorGreaterEqual{}); + const auto binary_comparator_less_equal_def = lit("<=") > x3::attr(ast::BinaryComparatorLessEqual{}); + const auto binary_comparator_def = binary_comparator_greater | binary_comparator_less | binary_comparator_equal | binary_comparator_greater_equal | binary_comparator_less_equal; + + const auto function_head_def = ((lit('(') >> function_symbol > *term) > lit(')')) | (function_symbol > x3::attr(std::vector{})); + const auto function_expression_def = function_expression_binary_op | function_expression_minus | function_expression_head | function_expression_number; + const auto function_expression_number_def = number; + // distinguishing unary from binary minus requires some more backtracking + const auto function_expression_binary_op_def = (lit('(') >> binary_operator >> function_expression >> function_expression) > lit(')'); + const auto function_expression_minus_def = (lit('(') >> lit('-')) >> function_expression > lit(')'); + const auto function_expression_head_def = function_head; + + const auto goal_descriptor_def = goal_descriptor_not | goal_descriptor_and | goal_descriptor_or | goal_descriptor_imply + | goal_descriptor_exists | goal_descriptor_forall | goal_descriptor_function_comparison | goal_descriptor_atom | goal_descriptor_literal; + const auto goal_descriptor_atom_def = atom; + const auto goal_descriptor_literal_def = literal; + const auto goal_descriptor_and_def = (lit('(') >> keyword_lit("and")) > *goal_descriptor > lit(')'); + const auto goal_descriptor_or_def = (lit('(') >> keyword_lit("or") > *goal_descriptor) > lit(')'); + const auto goal_descriptor_not_def = (lit('(') >> keyword_lit("not")) > goal_descriptor > lit(')'); + const auto goal_descriptor_imply_def = (lit('(') >> keyword_lit("imply")) > goal_descriptor > goal_descriptor > lit(')'); + const auto goal_descriptor_exists_def = (lit('(') >> keyword_lit("exists")) > lit('(') > typed_list_of_variables > lit(')') > goal_descriptor > lit(')'); + const auto goal_descriptor_forall_def = (lit('(') >> keyword_lit("forall")) > lit('(') > typed_list_of_variables > lit(')') > goal_descriptor > lit(')'); + const auto goal_descriptor_function_comparison_def = (lit('(') >> binary_comparator) >> function_expression > function_expression > lit(')'); + + const auto constraint_goal_descriptor_def = constraint_goal_descriptor_and | constraint_goal_descriptor_forall | constraint_goal_descriptor_at_end + | constraint_goal_descriptor_always | constraint_goal_descriptor_sometime | constraint_goal_descriptor_within + | constraint_goal_descriptor_at_most_once | constraint_goal_descriptor_sometime_after | constraint_goal_descriptor_sometime_before + | constraint_goal_descriptor_always_within | constraint_goal_descriptor_hold_during | constraint_goal_descriptor_hold_after; + const auto constraint_goal_descriptor_and_def = (lit('(') >> keyword_lit("and")) > *constraint_goal_descriptor > lit(')'); + const auto constraint_goal_descriptor_forall_def = (lit('(') >> keyword_lit("forall")) > lit('(') > typed_list_of_variables > lit(')') > constraint_goal_descriptor > lit(')'); + const auto constraint_goal_descriptor_at_end_def = (lit('(') >> keyword_lit("at") >> keyword_lit("end")) > goal_descriptor > lit(')'); + const auto constraint_goal_descriptor_always_def = (lit('(') >> keyword_lit("always")) > goal_descriptor > lit(')'); + const auto constraint_goal_descriptor_sometime_def = (lit('(') >> keyword_lit("sometime")) > goal_descriptor > lit(')'); + const auto constraint_goal_descriptor_within_def = (lit('(') >> keyword_lit("within")) > number > goal_descriptor > lit(')'); + const auto constraint_goal_descriptor_at_most_once_def = (lit('(') >> keyword_lit("at-most-once")) > goal_descriptor > lit(')'); + const auto constraint_goal_descriptor_sometime_after_def = (lit('(') >> keyword_lit("sometime-after")) > goal_descriptor > goal_descriptor > lit(')'); + const auto constraint_goal_descriptor_sometime_before_def = (lit('(') >> keyword_lit("sometime-before")) > goal_descriptor > goal_descriptor > lit(')'); + const auto constraint_goal_descriptor_always_within_def = (lit('(') >> keyword_lit("always-within")) > number > goal_descriptor > goal_descriptor > lit(')'); + const auto constraint_goal_descriptor_hold_during_def = (lit('(') >> keyword_lit("hold-during")) > number > number > goal_descriptor > lit(')'); + const auto constraint_goal_descriptor_hold_after_def = (lit('(') >> keyword_lit("hold-after")) > number > goal_descriptor > lit(')'); + + const auto precondition_goal_descriptor_def = precondition_goal_descriptor_and | precondition_goal_descriptor_preference | precondition_goal_descriptor_forall | precondition_goal_descriptor_simple; + const auto preference_name_def = name; + const auto precondition_goal_descriptor_simple_def = goal_descriptor; + const auto precondition_goal_descriptor_and_def = (lit('(') >> keyword_lit("and") > *precondition_goal_descriptor) > lit(')'); + const auto precondition_goal_descriptor_preference_def = (lit('(') >> keyword_lit("preference")) > preference_name > goal_descriptor > lit(')'); + const auto precondition_goal_descriptor_forall_def = (lit('(') >> keyword_lit("forall")) > lit('(') > typed_list_of_variables > lit(')') > precondition_goal_descriptor > lit(')'); + + const auto assign_operator_assign_def = keyword_lit("assign") > x3::attr(ast::AssignOperatorAssign{}); + const auto assign_operator_scale_up_def = keyword_lit("scale-up") > x3::attr(ast::AssignOperatorScaleUp{}); + const auto assign_operator_scale_down_def = keyword_lit("scale-down") > x3::attr(ast::AssignOperatorScaleDown{}); + const auto assign_operator_increase_def = keyword_lit("increase") > x3::attr(ast::AssignOperatorIncrease{}); + const auto assign_operator_decrease_def = keyword_lit("decrease") > x3::attr(ast::AssignOperatorDecrease{}); + const auto assign_operator_def = assign_operator_assign | assign_operator_scale_up | assign_operator_scale_down | assign_operator_increase | assign_operator_decrease; + + // For action cost effects only + const auto numeric_term_def = function_expression_number | function_expression_head; + + const auto effect_def = ((lit('(') >> keyword_lit("and")) > *effect > lit(')')) | effect_conditional | effect_production; + const auto effect_production_literal_def = literal; + const auto effect_production_numeric_fluent_total_cost_def = (lit('(') >> assign_operator_increase >> lit('(') >> function_symbol_total_cost) > lit(')') > numeric_term > lit(')'); + const auto effect_production_numeric_fluent_general_def = (lit('(') >> assign_operator >> function_head >> function_expression) > lit(')'); + const auto effect_production_def = effect_production_numeric_fluent_total_cost | effect_production_numeric_fluent_general | effect_production_literal; + const auto effect_conditional_forall_def = (lit('(') >> keyword_lit("forall")) > lit("(") > typed_list_of_variables > lit(')') > effect > lit(')'); + const auto effect_conditional_when_def = (lit('(') >> keyword_lit("when")) > goal_descriptor > effect > lit(')'); + const auto effect_conditional_def = effect_conditional_forall | effect_conditional_when; + + const auto action_symbol_def = name; + const auto action_body_def = -(keyword_lit(":precondition") > ((lit('(') >> lit(')')) | precondition_goal_descriptor)) + > -(keyword_lit(":effect") > ((lit('(') >> lit(')')) | effect)); + const auto action_def = (lit('(') >> keyword_lit(":action")) > action_symbol + > keyword_lit(":parameters") > lit('(') > typed_list_of_variables > lit(')') + > action_body + >> lit(')'); + + const auto derived_predicate_def = (lit('(') >> typed_list_of_variables >> goal_descriptor) > lit(')'); + + const auto define_keyword_def = keyword_lit("define"); + const auto domain_keyword_def = keyword_lit("domain"); + const auto domain_name_def = (lit('(') > domain_keyword) > name > lit(')'); + const auto requirements_def = lit('(') >> keyword_lit(":requirements") > *requirement >> lit(')'); + const auto types_def = (lit('(') >> keyword_lit(":types") > typed_list_of_names) > lit(')'); + const auto constants_def = (lit('(') >> keyword_lit(":constants") > typed_list_of_names) > lit(')'); + const auto predicates_def = (lit('(') >> keyword_lit(":predicates") > *atomic_formula_skeleton) > lit(')'); + const auto functions_def = (lit('(') >> keyword_lit(":functions") > *function_typed_list_of_atomic_function_skeletons) > lit(')'); + const auto constraints_def = (lit('(') >> keyword_lit(":constraints")) > constraint_goal_descriptor > lit(')'); + const auto structure_def = action | derived_predicate; + + const auto domain_def = + lit('(') > define_keyword + > domain_name + > -requirements + > -types + > -constants + > -predicates + > -functions + > -constraints + > *structure + > lit(')'); + + + BOOST_SPIRIT_DEFINE(name, variable, name_total_cost, function_symbol_total_cost, function_symbol, term, number, predicate) + + BOOST_SPIRIT_DEFINE(requirement_strips, requirement_typing, requirement_negative_preconditions, + requirement_disjunctive_preconditions, requirement_equality, requirement_existential_preconditions, + requirement_universal_preconditions, requirement_quantified_preconditions, + requirement_conditional_effects, requirement_fluents, requirement_object_fluents, + requirement_numeric_fluents, requirement_adl, requirement_durative_actions, + requirement_derived_predicates, requirement_timed_initial_literals, requirement_preferences, + requirement_constraints, requirement_action_costs, requirement) + + BOOST_SPIRIT_DEFINE(type, type_object, type_number, type_either, typed_list_of_names_recursively, + typed_list_of_names, typed_list_of_variables_recursively, typed_list_of_variables) + + BOOST_SPIRIT_DEFINE(atomic_formula_skeleton) + + BOOST_SPIRIT_DEFINE(atomic_function_skeleton_total_cost, atomic_function_skeleton_general, atomic_function_skeleton, + function_typed_list_of_atomic_function_skeletons_recursively, function_typed_list_of_atomic_function_skeletons) + + BOOST_SPIRIT_DEFINE(atomic_formula_of_terms_predicate, atomic_formula_of_terms_equality, + atomic_formula_of_terms, atom, negated_atom, literal) + + BOOST_SPIRIT_DEFINE(multi_operator_mul, multi_operator_plus, multi_operator, + binary_operator_minus, binary_operator_div, binary_operator) + + BOOST_SPIRIT_DEFINE(binary_comparator_greater, binary_comparator_less, binary_comparator_equal, + binary_comparator_greater_equal, binary_comparator_less_equal, binary_comparator) + + BOOST_SPIRIT_DEFINE(function_head, function_expression, function_expression_number, + function_expression_binary_op, function_expression_minus, function_expression_head) + + BOOST_SPIRIT_DEFINE(goal_descriptor, goal_descriptor_atom, goal_descriptor_literal, + goal_descriptor_and, goal_descriptor_or, goal_descriptor_not, goal_descriptor_imply, + goal_descriptor_exists, goal_descriptor_forall, goal_descriptor_function_comparison) + + BOOST_SPIRIT_DEFINE(constraint_goal_descriptor, constraint_goal_descriptor_and, + constraint_goal_descriptor_forall, constraint_goal_descriptor_at_end, + constraint_goal_descriptor_always, constraint_goal_descriptor_sometime, + constraint_goal_descriptor_within, constraint_goal_descriptor_at_most_once, + constraint_goal_descriptor_sometime_after, constraint_goal_descriptor_sometime_before, + constraint_goal_descriptor_always_within, constraint_goal_descriptor_hold_during, + constraint_goal_descriptor_hold_after) + + BOOST_SPIRIT_DEFINE(preference_name, precondition_goal_descriptor, precondition_goal_descriptor_simple, + precondition_goal_descriptor_and, precondition_goal_descriptor_preference, precondition_goal_descriptor_forall) + + BOOST_SPIRIT_DEFINE(assign_operator_assign, assign_operator_scale_up, assign_operator_scale_down, + assign_operator_increase, assign_operator_decrease, assign_operator) + + BOOST_SPIRIT_DEFINE(numeric_term) + + BOOST_SPIRIT_DEFINE(effect, effect_production_literal, + effect_production_numeric_fluent_total_cost, effect_production_numeric_fluent_general, + effect_production, effect_conditional_forall, + effect_conditional_when, effect_conditional, action_symbol, + action_body, action, derived_predicate) + + BOOST_SPIRIT_DEFINE(define_keyword, domain_keyword, domain_name, requirements, types, + constants, predicates, functions, constraints, structure, domain) + + + /////////////////////////////////////////////////////////////////////////// + // Annotation and Error handling + /////////////////////////////////////////////////////////////////////////// + + struct NameClass : x3::annotate_on_success {}; + struct VariableClass : x3::annotate_on_success {}; + struct NameTotalCostClass : x3::annotate_on_success {}; + struct FunctionSymbolTotalCostClass : x3::annotate_on_success {}; + struct FunctionSymbolClass : x3::annotate_on_success {}; + struct TermClass : x3::annotate_on_success {}; + struct NumberClass : x3::annotate_on_success {}; + struct PredicateClass : x3::annotate_on_success {}; + + struct RequirementStripsClass : x3::annotate_on_success {}; + struct RequirementTypingClass : x3::annotate_on_success {}; + struct RequirementNegativePreconditionsClass : x3::annotate_on_success {}; + struct RequirementDisjunctivePreconditionsClass : x3::annotate_on_success {}; + struct RequirementEqualityClass : x3::annotate_on_success {}; + struct RequirementExistentialPreconditionsClass : x3::annotate_on_success {}; + struct RequirementUniversalPreconditionsClass : x3::annotate_on_success {}; + struct RequirementQuantifiedPreconditionsClass : x3::annotate_on_success {}; + struct RequirementConditionalEffectsClass : x3::annotate_on_success {}; + struct RequirementFluentsClass : x3::annotate_on_success {}; + struct RequirementObjectFluentsClass : x3::annotate_on_success {}; + struct RequirementNumericalFluentsClass : x3::annotate_on_success {}; + struct RequirementAdlClass : x3::annotate_on_success {}; + struct RequirementDurativeActionsClass : x3::annotate_on_success {}; + struct RequirementDerivedPredicatesClass : x3::annotate_on_success {}; + struct RequirementTimedInitialLiteralsClass : x3::annotate_on_success {}; + struct RequirementPreferencesClass : x3::annotate_on_success {}; + struct RequirementConstraintsClass : x3::annotate_on_success {}; + struct RequirementActionCostsClass : x3::annotate_on_success {}; + struct RequirementClass : x3::annotate_on_success {}; + + struct TypeClass : x3::annotate_on_success {}; + struct TypeObjectClass : x3::annotate_on_success {}; + struct TypeNumberClass : x3::annotate_on_success {}; + struct TypeEitherClass : x3::annotate_on_success {}; + struct TypedListOfNamesRecursivelyClass : x3::annotate_on_success {}; + struct TypedListOfNamesClass : x3::annotate_on_success {}; + struct TypedListOfVariablesRecursivelyClass : x3::annotate_on_success {}; + struct TypedListOfVariablesClass : x3::annotate_on_success {}; + + struct AtomicFormulaSkeletonClass : x3::annotate_on_success {}; + + struct AtomicFunctionSkeletonTotalCostClass : x3::annotate_on_success {}; + struct AtomicFunctionSkeletonGeneralClass : x3::annotate_on_success {}; + struct AtomicFunctionSkeletonClass : x3::annotate_on_success {}; + struct FunctionTypedListOfAtomicFunctionSkeletonsRecursivelyClass : x3::annotate_on_success {}; + struct FunctionTypedListOfAtomicFunctionSkeletonsClass : x3::annotate_on_success {}; + + struct AtomicFormulaOfTermsPredicateClass : x3::annotate_on_success {}; + struct AtomicFormulaOfTermsEqualityClass : x3::annotate_on_success {}; + struct AtomicFormulaOfTermsClass : x3::annotate_on_success {}; + struct AtomClass : x3::annotate_on_success {}; + struct NegatedAtomClass : x3::annotate_on_success {}; + struct LiteralClass : x3::annotate_on_success {}; + + struct MultiOperatorMulClass : x3::annotate_on_success {}; + struct MultiOperatorPlusClass : x3::annotate_on_success {}; + struct MultiOperatorClass : x3::annotate_on_success {}; + struct BinaryOperatorMinusClass : x3::annotate_on_success {}; + struct BinaryOperatorDivClass : x3::annotate_on_success {}; + struct BinaryOperatorClass : x3::annotate_on_success {}; + + struct BinaryComparatorGreaterClass : x3::annotate_on_success {}; + struct BinaryComparatorLessClass : x3::annotate_on_success {}; + struct BinaryComparatorEqualClass : x3::annotate_on_success {}; + struct BinaryComparatorGreaterEqualClass : x3::annotate_on_success {}; + struct BinaryComparatorLessEqualClass : x3::annotate_on_success {}; + struct BinaryComparatorClass : x3::annotate_on_success {}; + + struct FunctionExpressionClass : x3::annotate_on_success {}; + struct FunctionHeadClass : x3::annotate_on_success {}; + struct FunctionExpressionNumberClass : x3::annotate_on_success {}; + struct FunctionExpressionBinaryOpClass : x3::annotate_on_success {}; + struct FunctionExpressionMinusClass : x3::annotate_on_success {}; + struct FunctionExpressionHeadClass : x3::annotate_on_success {}; + + struct GoalDescriptorClass : x3::annotate_on_success {}; + struct GoalDescriptorAtomClass : x3::annotate_on_success {}; + struct GoalDescriptorLiteralClass : x3::annotate_on_success {}; + struct GoalDescriptorAndClass : x3::annotate_on_success {}; + struct GoalDescriptorOrClass : x3::annotate_on_success {}; + struct GoalDescriptorNotClass : x3::annotate_on_success {}; + struct GoalDescriptorImplyClass : x3::annotate_on_success {}; + struct GoalDescriptorExistsClass : x3::annotate_on_success {}; + struct GoalDescriptorForallClass : x3::annotate_on_success {}; + struct GoalDescriptorFunctionComparisonClass : x3::annotate_on_success {}; + + struct ConstraintGoalDescriptorClass : x3::annotate_on_success {}; + struct ConstraintGoalDescriptorAndClass : x3::annotate_on_success {}; + struct ConstraintGoalDescriptorForallClass : x3::annotate_on_success {}; + struct ConstraintGoalDescriptorAtEndClass : x3::annotate_on_success {}; + struct ConstraintGoalDescriptorAlwaysClass : x3::annotate_on_success {}; + struct ConstraintGoalDescriptorSometimeClass : x3::annotate_on_success {}; + struct ConstraintGoalDescriptorWithinClass : x3::annotate_on_success {}; + struct ConstraintGoalDescriptorAtMostOnceClass : x3::annotate_on_success {}; + struct ConstraintGoalDescriptorSometimeAfterClass : x3::annotate_on_success {}; + struct ConstraintGoalDescriptorSometimeBeforeClass : x3::annotate_on_success {}; + struct ConstraintGoalDescriptorAlwaysWithinClass : x3::annotate_on_success {}; + struct ConstraintGoalDescriptorHoldDuringClass : x3::annotate_on_success {}; + struct ConstraintGoalDescriptorHoldAfterClass : x3::annotate_on_success {}; + + struct PreferenceNameClass : x3::annotate_on_success {}; + struct PreconditionGoalDescriptorClass : x3::annotate_on_success {}; + struct PreconditionGoalDescriptorSimpleClass : x3::annotate_on_success {}; + struct PreconditionGoalDescriptorAndClass : x3::annotate_on_success {}; + struct PreconditionGoalDescriptorPreferenceClass : x3::annotate_on_success {}; + struct PreconditionGoalDescriptorForallClass : x3::annotate_on_success {}; + + struct AssignOperatorAssignClass : x3::annotate_on_success {}; + struct AssignOperatorScaleUpClass : x3::annotate_on_success {}; + struct AssignOperatorScaleDownClass : x3::annotate_on_success {}; + struct AssignOperatorIncreaseClass : x3::annotate_on_success {}; + struct AssignOperatorDecreaseClass : x3::annotate_on_success {}; + struct AssignOperatorClass : x3::annotate_on_success {}; + + struct NumericTermClass : x3::annotate_on_success {}; + + struct EffectClass : x3::annotate_on_success {}; + struct EffectProductionLiteralClass : x3::annotate_on_success {}; + struct EffectProductionNumericFluentTotalCostClass : x3::annotate_on_success {}; + struct EffectProductionNumericFluentGeneralClass : x3::annotate_on_success {}; + struct EffectProductionClass : x3::annotate_on_success {}; + struct EffectConditionalForallClass : x3::annotate_on_success {}; + struct EffectConditionalWhenClass : x3::annotate_on_success {}; + struct EffectConditionalClass : x3::annotate_on_success {}; + struct ActionSymbolClass : x3::annotate_on_success {}; + struct ActionBodyClass : x3::annotate_on_success {}; + struct ActionClass : x3::annotate_on_success {}; + struct DurativeActionClass : x3::annotate_on_success {}; + struct DerivedPredicateClass : x3::annotate_on_success {}; + + struct DomainNameClass : x3::annotate_on_success {}; + struct RequirementsClass : x3::annotate_on_success {}; + struct TypesClass : x3::annotate_on_success {}; + struct ConstantsClass : x3::annotate_on_success {}; + struct PredicatesClass : x3::annotate_on_success {}; + struct FunctionsClass : x3::annotate_on_success {}; + struct ConstraintsClass : x3::annotate_on_success {}; + struct StructureClass : x3::annotate_on_success {}; + struct DomainClass : x3::annotate_on_success, error_handler_domain {}; +} + +namespace loki::domain +{ + parser::define_keyword_type const& define_keyword() { + return parser::define_keyword; + } + parser::domain_keyword_type const& domain_keyword() { + return parser::domain_keyword; + } + + parser::name_type const& name() { + return parser::name; + } + parser::variable_type const& variable() { + return parser::variable; + } + parser::name_total_cost_type const& name_total_cost() { + return parser::name_total_cost; + } + parser::function_symbol_total_cost_type const& function_symbol_total_cost() { + return parser::function_symbol_total_cost; + } + parser::function_symbol_type const& function_symbol() { + return parser::function_symbol; + } + parser::term_type const& term() { + return parser::term; + } + parser::number_type const& number() { + return parser::number; + } + parser::predicate_type const& predicate() { + return parser::predicate; + } + + parser::requirement_strips_type const& requirement_strips() { + return parser::requirement_strips; + } + parser::requirement_typing_type const& requirement_typing() { + return parser::requirement_typing; + } + parser::requirement_negative_preconditions_type const& requirement_negative_preconditions() { + return parser::requirement_negative_preconditions; + } + parser::requirement_disjunctive_preconditions_type const& requirement_disjunctive_preconditions() { + return parser::requirement_disjunctive_preconditions; + } + parser::requirement_equality_type const& requirement_equality() { + return parser::requirement_equality; + } + parser::requirement_existential_preconditions_type const& requirement_existential_preconditions() { + return parser::requirement_existential_preconditions; + } + parser::requirement_universal_preconditions_type const& requirement_universal_preconditions() { + return parser::requirement_universal_preconditions; + } + parser::requirement_quantified_preconditions_type const& requirement_quantified_preconditions() { + return parser::requirement_quantified_preconditions; + } + parser::requirement_conditional_effects_type const& requirement_conditional_effects() { + return parser::requirement_conditional_effects; + } + parser::requirement_fluents_type const& requirement_fluents() { + return parser::requirement_fluents; + } + parser::requirement_object_fluents_type const& requirement_object_fluents() { + return parser::requirement_object_fluents; + } + parser::requirement_numeric_fluents_type const& requirement_numeric_fluents() { + return parser::requirement_numeric_fluents; + } + parser::requirement_adl_type const& requirement_adl() { + return parser::requirement_adl; + } + parser::requirement_durative_actions_type const& requirement_durative_actions() { + return parser::requirement_durative_actions; + } + parser::requirement_derived_predicates_type const& requirement_derived_predicates() { + return parser::requirement_derived_predicates; + } + parser::requirement_timed_initial_literals_type const& requirement_timed_initial_literals() { + return parser::requirement_timed_initial_literals; + } + parser::requirement_preferences_type const& requirement_preferences() { + return parser::requirement_preferences; + } + parser::requirement_constraints_type const& requirement_constraints() { + return parser::requirement_constraints; + } + parser::requirement_action_costs_type const& requirement_action_costs() { + return parser::requirement_action_costs; + } + parser::requirement_type const& requirement() { + return parser::requirement; + } + + parser::type_type const& type() { + return parser::type; + } + parser::type_object_type const& type_object() { + return parser::type_object; + } + parser::type_number_type const& type_number() { + return parser::type_number; + } + parser::type_either_type const& type_either() { + return parser::type_either; + } + parser::typed_list_of_names_recursively_type const& typed_list_of_names_recursively() { + return parser::typed_list_of_names_recursively; + } + parser::typed_list_of_names_type const& typed_list_of_names() { + return parser::typed_list_of_names; + } + parser::typed_list_of_variables_recursively_type const& typed_list_of_variables_recursively() { + return parser::typed_list_of_variables_recursively; + } + parser::typed_list_of_variables_type const& typed_list_of_variables() { + return parser::typed_list_of_variables; + } + + parser::atomic_formula_skeleton_type const& atomic_formula_skeleton() { + return parser::atomic_formula_skeleton; + } + + parser::atomic_function_skeleton_total_cost_type const& atomic_function_skeleton_total_cost() { + return parser::atomic_function_skeleton_total_cost; + } + parser::atomic_function_skeleton_general_type const& atomic_function_skeleton_general() { + return parser::atomic_function_skeleton_general; + } + parser::atomic_function_skeleton_type const& atomic_function_skeleton() { + return parser::atomic_function_skeleton; + } + parser::function_typed_list_of_atomic_function_skeletons_recursively_type const& function_typed_list_of_atomic_function_skeletons_recursively() { + return parser::function_typed_list_of_atomic_function_skeletons_recursively; + } + parser::function_typed_list_of_atomic_function_skeletons_type const& function_typed_list_of_atomic_function_skeletons() { + return parser::function_typed_list_of_atomic_function_skeletons; + } + + parser::atomic_formula_of_terms_predicate_type const& atomic_formula_of_terms_predicate() { + return parser::atomic_formula_of_terms_predicate; + } + parser::atomic_formula_of_terms_equality_type const& atomic_formula_of_terms_equality() { + return parser::atomic_formula_of_terms_equality; + } + parser::atomic_formula_of_terms_type const& atomic_formula_of_terms() { + return parser::atomic_formula_of_terms; + } + parser::atom_type const& atom() { + return parser::atom; + } + parser::negated_atom_type const& negated_atom() { + return parser::negated_atom; + } + parser::literal_type const& literal() { + return parser::literal; + } + + parser::multi_operator_mul_type const& multi_operator_mul() { + return parser::multi_operator_mul; + } + parser::multi_operator_plus_type const& multi_operator_plus() { + return parser::multi_operator_plus; + } + parser::multi_operator_type const& multi_operator() { + return parser::multi_operator; + } + parser::binary_operator_minus_type const& binary_operator_minus() { + return parser::binary_operator_minus; + } + parser::binary_operator_div_type const& binary_operator_div() { + return parser::binary_operator_div; + } + parser::binary_operator_type const& binary_operator() { + return parser::binary_operator; + } + + parser::binary_comparator_greater_type const& binary_comparator_greater() { + return parser::binary_comparator_greater; + } + parser::binary_comparator_less_type const& binary_comparator_less() { + return parser::binary_comparator_less; + } + parser::binary_comparator_equal_type const& binary_comparator_equal() { + return parser::binary_comparator_equal; + } + parser::binary_comparator_greater_equal_type const& binary_comparator_greater_equal() { + return parser::binary_comparator_greater_equal; + } + parser::binary_comparator_less_equal_type const& binary_comparator_less_equal() { + return parser::binary_comparator_less_equal; + } + parser::binary_comparator_type const& binary_comparator() { + return parser::binary_comparator; + } + + parser::function_expression_type const& function_expression() { + return parser::function_expression; + } + parser::function_head_type const& function_head() { + return parser::function_head; + } + parser::function_expression_number_type const& function_expression_number() { + return parser::function_expression_number; + } + parser::function_expression_binary_op_type const& function_expression_binary_op() { + return parser::function_expression_binary_op; + } + parser::function_expression_minus_type const& function_expression_minus() { + return parser::function_expression_minus; + } + parser::function_expression_head_type const& function_expression_head() { + return parser::function_expression_head; + } + + parser::goal_descriptor_type const& goal_descriptor() { + return parser::goal_descriptor; + } + parser::goal_descriptor_atom_type const& goal_descriptor_atom() { + return parser::goal_descriptor_atom; + } + parser::goal_descriptor_literal_type const& goal_descriptor_literal() { + return parser::goal_descriptor_literal; + } + parser::goal_descriptor_and_type const& goal_descriptor_and() { + return parser::goal_descriptor_and; + } + parser::goal_descriptor_or_type const& goal_descriptor_or() { + return parser::goal_descriptor_or; + } + parser::goal_descriptor_not_type const& goal_descriptor_not() { + return parser::goal_descriptor_not; + } + parser::goal_descriptor_imply_type const& goal_descriptor_imply() { + return parser::goal_descriptor_imply; + } + parser::goal_descriptor_exists_type const& goal_descriptor_exists() { + return parser::goal_descriptor_exists; + } + parser::goal_descriptor_forall_type const& goal_descriptor_forall() { + return parser::goal_descriptor_forall; + } + parser::goal_descriptor_function_comparison_type const& goal_descriptor_function_comparison() { + return parser::goal_descriptor_function_comparison; + } + + parser::constraint_goal_descriptor_type const& constraint_goal_descriptor() { + return parser::constraint_goal_descriptor; + } + parser::constraint_goal_descriptor_and_type const& constraint_goal_descriptor_and() { + return parser::constraint_goal_descriptor_and; + } + parser::constraint_goal_descriptor_forall_type const& constraint_goal_descriptor_forall() { + return parser::constraint_goal_descriptor_forall; + } + parser::constraint_goal_descriptor_at_end_type const& constraint_goal_descriptor_at_end() { + return parser::constraint_goal_descriptor_at_end; + } + parser::constraint_goal_descriptor_always_type const& constraint_goal_descriptor_always() { + return parser::constraint_goal_descriptor_always; + } + parser::constraint_goal_descriptor_sometime_type const& constraint_goal_descriptor_sometime() { + return parser::constraint_goal_descriptor_sometime; + } + parser::constraint_goal_descriptor_within_type const& constraint_goal_descriptor_within() { + return parser::constraint_goal_descriptor_within; + } + parser::constraint_goal_descriptor_at_most_once_type const& constraint_goal_descriptor_at_most_once() { + return parser::constraint_goal_descriptor_at_most_once; + } + parser::constraint_goal_descriptor_sometime_after_type const& constraint_goal_descriptor_sometime_after() { + return parser::constraint_goal_descriptor_sometime_after; + } + parser::constraint_goal_descriptor_sometime_before_type const& constraint_goal_descriptor_sometime_before() { + return parser::constraint_goal_descriptor_sometime_before; + } + parser::constraint_goal_descriptor_always_within_type const& constraint_goal_descriptor_always_within() { + return parser::constraint_goal_descriptor_always_within; + } + parser::constraint_goal_descriptor_hold_during_type const& constraint_goal_descriptor_hold_during() { + return parser::constraint_goal_descriptor_hold_during; + } + parser::constraint_goal_descriptor_hold_after_type const& constraint_goal_descriptor_hold_after() { + return parser::constraint_goal_descriptor_hold_after; + } + + parser::precondition_goal_descriptor_type const& precondition_goal_descriptor() { + return parser::precondition_goal_descriptor; + } + parser::preference_name_type const& preference_name() { + return parser::preference_name; + } + parser::precondition_goal_descriptor_simple_type const& precondition_goal_descriptor_simple() { + return parser::precondition_goal_descriptor_simple; + } + parser::precondition_goal_descriptor_and_type const& precondition_goal_descriptor_and() { + return parser::precondition_goal_descriptor_and; + } + parser::precondition_goal_descriptor_preference_type const& precondition_goal_descriptor_preference() { + return parser::precondition_goal_descriptor_preference; + } + parser::precondition_goal_descriptor_forall_type const& precondition_goal_descriptor_forall() { + return parser::precondition_goal_descriptor_forall; + } + + parser::assign_operator_assign_type const& assign_operator_assign() { + return parser::assign_operator_assign; + } + parser::assign_operator_scale_up_type const& assign_operator_scale_up() { + return parser::assign_operator_scale_up; + } + parser::assign_operator_scale_down_type const& assign_operator_scale_down() { + return parser::assign_operator_scale_down; + } + parser::assign_operator_increase_type const& assign_operator_increase() { + return parser::assign_operator_increase; + } + parser::assign_operator_decrease_type const& assign_operator_decrease() { + return parser::assign_operator_decrease; + } + parser::assign_operator_type const& assign_operator() { + return parser::assign_operator; + } + + parser::numeric_term_type const& numeric_term() { + return parser::numeric_term; + } + + parser::effect_type const& effect() { + return parser::effect; + } + parser::effect_production_literal_type const& effect_production_literal() { + return parser::effect_production_literal; + } + parser::effect_production_numeric_fluent_total_cost_type const& effect_production_numeric_fluent_total_cost() { + return parser::effect_production_numeric_fluent_total_cost; + } + parser::effect_production_numeric_fluent_general_type const& effect_production_numeric_fluent_general() { + return parser::effect_production_numeric_fluent_general; + } + parser::effect_production_type const& effect_production() { + return parser::effect_production; + } + parser::effect_conditional_forall_type const& effect_conditional_forall() { + return parser::effect_conditional_forall; + } + parser::effect_conditional_when_type const& effect_conditional_when() { + return parser::effect_conditional_when; + } + parser::effect_conditional_type const& effect_conditional() { + return parser::effect_conditional; + } + parser::action_symbol_type const& action_symbol() { + return parser::action_symbol; + } + parser::action_body_type const& action_body() { + return parser::action_body; + } + parser::action_type const& action() { + return parser::action; + } + parser::derived_predicate_type const& derived_predicate() { + return parser::derived_predicate; + } + + parser::domain_name_type const& domain_name() { + return parser::domain_name; + } + parser::requirements_type const& requirements() { + return parser::requirements; + } + parser::types_type const& types() { + return parser::types; + } + parser::constants_type const& constants() { + return parser::constants; + } + parser::predicates_type const& predicates() { + return parser::predicates; + } + parser::functions_type const& functions() { + return parser::functions; + } + parser::constraints_type const& constraints() { + return parser::constraints; + } + parser::structure_type const& structure() { + return parser::structure; + } + parser::domain_type const& domain() { + return parser::domain; + } +} + +#endif diff --git a/src/domain/ast/parser_instantiations.cpp b/src/domain/ast/parser_instantiations.cpp new file mode 100644 index 00000000..a5e8581d --- /dev/null +++ b/src/domain/ast/parser_instantiations.cpp @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "parser_def.hpp" + +#include "../../../include/loki/common/ast/config.hpp" + + +namespace loki::domain::parser +{ + using iterator_type = loki::iterator_type; + using phrase_context_type = loki::phrase_context_type; + using context_type = loki::context_type; + + BOOST_SPIRIT_INSTANTIATE(name_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(variable_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(name_total_cost_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(function_symbol_total_cost_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(function_symbol_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(term_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(number_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(predicate_type, iterator_type, context_type) + + BOOST_SPIRIT_INSTANTIATE(requirement_strips_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(requirement_typing_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(requirement_negative_preconditions_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(requirement_disjunctive_preconditions_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(requirement_equality_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(requirement_existential_preconditions_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(requirement_universal_preconditions_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(requirement_quantified_preconditions_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(requirement_conditional_effects_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(requirement_fluents_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(requirement_object_fluents_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(requirement_numeric_fluents_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(requirement_adl_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(requirement_durative_actions_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(requirement_derived_predicates_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(requirement_timed_initial_literals_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(requirement_preferences_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(requirement_constraints_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(requirement_action_costs_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(requirement_type, iterator_type, context_type) + + BOOST_SPIRIT_INSTANTIATE(type_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(type_object_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(type_number_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(type_either_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(typed_list_of_names_recursively_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(typed_list_of_names_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(typed_list_of_variables_recursively_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(typed_list_of_variables_type, iterator_type, context_type) + + BOOST_SPIRIT_INSTANTIATE(atomic_formula_skeleton_type, iterator_type, context_type) + + BOOST_SPIRIT_INSTANTIATE(atomic_function_skeleton_total_cost_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(atomic_function_skeleton_general_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(atomic_function_skeleton_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(function_typed_list_of_atomic_function_skeletons_recursively_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(function_typed_list_of_atomic_function_skeletons_type, iterator_type, context_type) + + BOOST_SPIRIT_INSTANTIATE(atomic_formula_of_terms_predicate_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(atomic_formula_of_terms_equality_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(atomic_formula_of_terms_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(atom_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(negated_atom_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(literal_type, iterator_type, context_type) + + BOOST_SPIRIT_INSTANTIATE(multi_operator_mul_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(multi_operator_plus_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(multi_operator_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(binary_operator_minus_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(binary_operator_div_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(binary_operator_type, iterator_type, context_type) + + BOOST_SPIRIT_INSTANTIATE(binary_comparator_greater_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(binary_comparator_less_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(binary_comparator_equal_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(binary_comparator_greater_equal_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(binary_comparator_less_equal_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(binary_comparator_type, iterator_type, context_type) + + BOOST_SPIRIT_INSTANTIATE(function_expression_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(function_head_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(function_expression_number_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(function_expression_binary_op_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(function_expression_minus_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(function_expression_head_type, iterator_type, context_type) + + BOOST_SPIRIT_INSTANTIATE(goal_descriptor_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(goal_descriptor_atom_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(goal_descriptor_literal_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(goal_descriptor_and_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(goal_descriptor_or_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(goal_descriptor_not_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(goal_descriptor_imply_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(goal_descriptor_exists_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(goal_descriptor_forall_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(goal_descriptor_function_comparison_type, iterator_type, context_type) + + BOOST_SPIRIT_INSTANTIATE(constraint_goal_descriptor_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(constraint_goal_descriptor_and_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(constraint_goal_descriptor_forall_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(constraint_goal_descriptor_at_end_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(constraint_goal_descriptor_always_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(constraint_goal_descriptor_sometime_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(constraint_goal_descriptor_within_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(constraint_goal_descriptor_at_most_once_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(constraint_goal_descriptor_sometime_after_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(constraint_goal_descriptor_sometime_before_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(constraint_goal_descriptor_always_within_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(constraint_goal_descriptor_hold_during_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(constraint_goal_descriptor_hold_after_type, iterator_type, context_type) + + BOOST_SPIRIT_INSTANTIATE(precondition_goal_descriptor_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(preference_name_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(precondition_goal_descriptor_simple_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(precondition_goal_descriptor_and_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(precondition_goal_descriptor_preference_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(precondition_goal_descriptor_forall_type, iterator_type, context_type) + + BOOST_SPIRIT_INSTANTIATE(assign_operator_assign_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(assign_operator_scale_up_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(assign_operator_scale_down_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(assign_operator_increase_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(assign_operator_decrease_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(assign_operator_type, iterator_type, context_type) + + BOOST_SPIRIT_INSTANTIATE(numeric_term_type, iterator_type, context_type) + + BOOST_SPIRIT_INSTANTIATE(effect_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(effect_production_literal_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(effect_production_numeric_fluent_total_cost_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(effect_production_numeric_fluent_general_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(effect_production_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(effect_conditional_forall_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(effect_conditional_when_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(effect_conditional_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(action_symbol_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(action_body_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(action_type, iterator_type, context_type) + + BOOST_SPIRIT_INSTANTIATE(derived_predicate_type, iterator_type, context_type) + + BOOST_SPIRIT_INSTANTIATE(define_keyword_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(domain_keyword_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(domain_name_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(requirements_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(types_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(constants_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(predicates_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(functions_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(constraints_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(structure_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(domain_type, iterator_type, context_type) +} diff --git a/src/domain/ast/printer.cpp b/src/domain/ast/printer.cpp new file mode 100644 index 00000000..80888c73 --- /dev/null +++ b/src/domain/ast/printer.cpp @@ -0,0 +1,702 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/domain/ast/printer.hpp" + +#include "../../../include/loki/problem/ast/printer.hpp" + +#include +#include + +using namespace std; + + +namespace loki +{ + // Printer for std::vector + template + inline std::string parse_text(const std::vector& nodes, const FormattingOptions& options); + + // Printer for boost::variant + class NodeVisitorPrinter : public boost::static_visitor { + private: + const FormattingOptions* options; + + public: + NodeVisitorPrinter(const FormattingOptions& options) : options(&options) { } + + template + std::string operator()(const Node& node) const + { + return parse_text(node, *options); + } + }; + + string parse_text(const domain::ast::Name& node, const FormattingOptions&) + { + return node.characters; + } + + string parse_text(const domain::ast::Variable& node, const FormattingOptions&) + { + return node.characters; + } + + std::string parse_text(const domain::ast::FunctionSymbol& node, const FormattingOptions& options) + { + return parse_text(node.name, options); + } + + string parse_text(const domain::ast::Term& node, const FormattingOptions& options) + { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + std::string parse_text(const domain::ast::Predicate& node, const FormattingOptions& options) + { + return parse_text(node.name, options); + } + + string parse_text(const domain::ast::Number& node, const FormattingOptions&) + { + stringstream ss; + ss << node.value; + return ss.str(); + } + + std::string parse_text(const domain::ast::RequirementStrips&, const FormattingOptions&) { return ":strips"; } + std::string parse_text(const domain::ast::RequirementTyping&, const FormattingOptions&) { return ":typing"; } + std::string parse_text(const domain::ast::RequirementNegativePreconditions&, const FormattingOptions&) { return ":negative-preconditions"; } + std::string parse_text(const domain::ast::RequirementDisjunctivePreconditions&, const FormattingOptions&) { return ":disjunctive-preconditions"; } + std::string parse_text(const domain::ast::RequirementEquality&, const FormattingOptions&) { return ":equality"; } + std::string parse_text(const domain::ast::RequirementExistentialPreconditions&, const FormattingOptions&) { return ":existential-preconditions"; } + std::string parse_text(const domain::ast::RequirementUniversalPreconditions&, const FormattingOptions&) { return ":universal-preconditions"; } + std::string parse_text(const domain::ast::RequirementQuantifiedPreconditions&, const FormattingOptions&) { return ":quantified-preconditions"; } + std::string parse_text(const domain::ast::RequirementConditionalEffects&, const FormattingOptions&) { return ":conditional-effects"; } + std::string parse_text(const domain::ast::RequirementFluents&, const FormattingOptions&) { return ":fluents"; } + std::string parse_text(const domain::ast::RequirementObjectFluents&, const FormattingOptions&) { return ":object-fluents"; } + std::string parse_text(const domain::ast::RequirementNumericFluents&, const FormattingOptions&) { return ":numeric-fluents"; } + std::string parse_text(const domain::ast::RequirementAdl&, const FormattingOptions&) { return ":adl"; } + std::string parse_text(const domain::ast::RequirementDurativeActions&, const FormattingOptions&) { return ":durative-actions"; } + std::string parse_text(const domain::ast::RequirementDerivedPredicates&, const FormattingOptions&) { return ":derived-predicates"; } + std::string parse_text(const domain::ast::RequirementTimedInitialLiterals&, const FormattingOptions&) { return ":timed-initial-literals"; } + std::string parse_text(const domain::ast::RequirementPreferences&, const FormattingOptions&) { return ":preferences"; } + std::string parse_text(const domain::ast::RequirementConstraints&, const FormattingOptions&) { return ":constraints"; } + std::string parse_text(const domain::ast::RequirementActionCosts&, const FormattingOptions&) { return ":action-costs";} + + std::string parse_text(const domain::ast::Requirement& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + + string parse_text(const domain::ast::Type& node, const FormattingOptions& options) + { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + string parse_text(const domain::ast::TypeObject& /*node*/, const FormattingOptions& /*options*/) + { + return "object"; + } + + string parse_text(const domain::ast::TypeNumber& /*node*/, const FormattingOptions& /*options*/) + { + return "number"; + } + + string parse_text(const domain::ast::TypeEither& node, const FormattingOptions& options) + { + stringstream ss; + ss << "(either "; + for (size_t i = 0; i < node.types.size(); ++i) + { + if (i != 0) + ss << " "; + ss << parse_text(node.types[i], options); + } + ss << ")"; + return ss.str(); + } + + string parse_text(const domain::ast::TypedListOfNamesRecursively& node, const FormattingOptions& options) + { + stringstream ss; + for (size_t i = 0; i < node.names.size(); ++i) + { + if (i != 0) + ss << " "; + ss << parse_text(node.names[i], options); + } + ss << " - " << parse_text(node.type, options); + + // lookahead + auto nested_options = FormattingOptions{options.indent + options.add_indent, options.add_indent}; + auto nested_text = parse_text(node.typed_list_of_names, nested_options); + if (nested_text.size() > 0) { + ss << "\n"; + ss << string(nested_options.indent, ' ') << nested_text; + } + return ss.str(); + } + + string parse_text(const domain::ast::TypedListOfNames& node, const FormattingOptions& options) + { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + std::string parse_text(const domain::ast::TypedListOfVariablesRecursively& node, const FormattingOptions& options) + { + stringstream ss; + for (size_t i = 0; i < node.variables.size(); ++i) + { + if (i != 0) + ss << " "; + ss << parse_text(node.variables[i]); + } + ss << " - " << parse_text(node.type, options); + + // lookahead + auto nested_options = FormattingOptions{options.indent + options.add_indent, options.add_indent}; + auto nested_text = parse_text(node.typed_list_of_variables, options); + if (nested_text.size() > 0) { + ss << "\n"; + ss << string(nested_options.indent, ' ') << nested_text; + } + return ss.str(); + } + + std::string parse_text(const domain::ast::TypedListOfVariables& node, const FormattingOptions& options) + { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + std::string parse_text(const domain::ast::AtomicFormulaSkeleton& node, const FormattingOptions& options) + { + std::stringstream ss; + ss << "(" + << parse_text(node.predicate, options) << " " + << parse_text(node.typed_list_of_variables, options) << ")"; + return ss.str(); + } + + + std::string parse_text(const domain::ast::AtomicFunctionSkeletonTotalCost& node, const FormattingOptions& options) + { + return parse_text(node.function_symbol, options); + } + + std::string parse_text(const domain::ast::AtomicFunctionSkeletonGeneral& node, const FormattingOptions& options) + { + std::stringstream ss; + ss << "(" + << parse_text(node.function_symbol, options) << " " + << parse_text(node.arguments, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::AtomicFunctionSkeleton& node, const FormattingOptions& options) + { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + std::string parse_text(const domain::ast::FunctionTypedListOfAtomicFunctionSkeletonsRecursively& node, const FormattingOptions& options) { + stringstream ss; + for (size_t i = 0; i < node.atomic_function_skeletons.size(); ++i) + { + if (i != 0) + ss << " "; + ss << parse_text(node.atomic_function_skeletons[i], options); + } + ss << " - " << parse_text(node.function_type, options); + + // lookahead + auto nested_options = FormattingOptions{options.indent + options.add_indent, options.add_indent}; + if (node.function_typed_list_of_atomic_function_skeletons.has_value()) { + auto nested_text = parse_text(node.function_typed_list_of_atomic_function_skeletons.value(), options); + if (nested_text.size() > 0) { + ss << "\n"; + ss << string(nested_options.indent, ' ') << nested_text; + } + } + return ss.str(); + } + + std::string parse_text(const domain::ast::FunctionTypedListOfAtomicFunctionSkeletons& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + + std::string parse_text(const domain::ast::AtomicFormulaOfTermsPredicate& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(" << parse_text(node.predicate, options) << " " << parse_text(node.terms, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::AtomicFormulaOfTermsEquality& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(" << "= " << parse_text(node.term_left, options) << " " << parse_text(node.term_right, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::AtomicFormulaOfTerms& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + std::string parse_text(const domain::ast::Atom& node, const FormattingOptions& options) { + return parse_text(node.atomic_formula_of_terms, options); + } + + std::string parse_text(const domain::ast::NegatedAtom& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(not " << parse_text(node.atomic_formula_of_terms, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::Literal& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + std::string parse_text(const domain::ast::MultiOperatorMul&, const FormattingOptions&) { return "*"; } + std::string parse_text(const domain::ast::MultiOperatorPlus&, const FormattingOptions&) { return "+"; } + std::string parse_text(const domain::ast::MultiOperator& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + std::string parse_text(const domain::ast::BinaryOperatorMinus&, const FormattingOptions&) { return "-"; } + std::string parse_text(const domain::ast::BinaryOperatorDiv&, const FormattingOptions&) { return "/"; } + std::string parse_text(const domain::ast::BinaryOperator& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + + std::string parse_text(const domain::ast::BinaryComparatorGreater&, const FormattingOptions&) { return ">"; } + std::string parse_text(const domain::ast::BinaryComparatorLess&, const FormattingOptions&) { return "<"; } + std::string parse_text(const domain::ast::BinaryComparatorEqual&, const FormattingOptions&) { return "="; } + std::string parse_text(const domain::ast::BinaryComparatorGreaterEqual&, const FormattingOptions&) { return ">="; } + std::string parse_text(const domain::ast::BinaryComparatorLessEqual&, const FormattingOptions&) { return "<="; } + std::string parse_text(const domain::ast::BinaryComparator& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + + std::string parse_text(const domain::ast::FunctionHead& node, const FormattingOptions& options) { + std::stringstream ss; + if (node.terms.size() > 0) { + ss << "(" << parse_text(node.function_symbol, options) << " " << parse_text(node.terms, options) << ")"; + } else { + ss << parse_text(node.function_symbol, options); + } + return ss.str(); + } + + std::string parse_text(const domain::ast::FunctionExpression& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + std::string parse_text(const domain::ast::FunctionExpressionNumber& node, const FormattingOptions& options) { + return parse_text(node.number, options); + } + + std::string parse_text(const domain::ast::FunctionExpressionBinaryOp& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(" << parse_text(node.binary_operator, options) << " " + << parse_text(node.function_expression_left, options) << " " + << parse_text(node.function_expression_right, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::FunctionExpressionMinus& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(- " << parse_text(node.function_expression, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::FunctionExpressionHead& node, const FormattingOptions& options) { + return parse_text(node.function_head, options); + } + + + std::string parse_text(const domain::ast::GoalDescriptor& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + std::string parse_text(const domain::ast::GoalDescriptorAtom& node, const FormattingOptions& options) { + return parse_text(node.atom, options); + } + + std::string parse_text(const domain::ast::GoalDescriptorLiteral& node, const FormattingOptions& options) { + return parse_text(node.literal, options); + } + + std::string parse_text(const domain::ast::GoalDescriptorAnd& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(and " << parse_text(node.goal_descriptors, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::GoalDescriptorOr& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(or " << parse_text(node.goal_descriptors, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::GoalDescriptorNot& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(not " << parse_text(node.goal_descriptor, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::GoalDescriptorImply& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(imply " << parse_text(node.goal_descriptor_left, options) << " " + << parse_text(node.goal_descriptor_right, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::GoalDescriptorExists& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(exists " << parse_text(node.typed_list_of_variables, options) << " " + << parse_text(node.goal_descriptor, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::GoalDescriptorForall& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(forall " << parse_text(node.typed_list_of_variables, options) << " " + << parse_text(node.goal_descriptor, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::GoalDescriptorFunctionComparison& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(" << parse_text(node.binary_comparator, options) << " " + << parse_text(node.function_expression_left, options) << " " + << parse_text(node.function_expression_right, options) << ")"; + return ss.str(); + } + + + std::string parse_text(const domain::ast::ConstraintGoalDescriptor& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + std::string parse_text(const domain::ast::ConstraintGoalDescriptorAnd& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(and " << parse_text(node.constraint_goal_descriptors, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::ConstraintGoalDescriptorForall& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(forall " << parse_text(node.typed_list_of_variables, options) << " " + << parse_text(node.constraint_goal_descriptor, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::ConstraintGoalDescriptorAtEnd& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(at end " << parse_text(node.goal_descriptor, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::ConstraintGoalDescriptorAlways& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(always " << parse_text(node.goal_descriptor, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::ConstraintGoalDescriptorSometime& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(sometime " << parse_text(node.goal_descriptor, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::ConstraintGoalDescriptorWithin& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(within " << parse_text(node.number, options) << " " + << parse_text(node.goal_descriptor, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::ConstraintGoalDescriptorAtMostOnce& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(at-most-once " << parse_text(node.goal_descriptor, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::ConstraintGoalDescriptorSometimeAfter& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(sometime-after " << parse_text(node.goal_descriptor_left, options) << " " + << parse_text(node.goal_descriptor_right, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::ConstraintGoalDescriptorSometimeBefore& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(sometime-before " << parse_text(node.goal_descriptor_left, options) << " " + << parse_text(node.goal_descriptor_right, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::ConstraintGoalDescriptorAlwaysWithin& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(always-within " << parse_text(node.number, options) << " " + << parse_text(node.goal_descriptor_left, options) << " " + << parse_text(node.goal_descriptor_right, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::ConstraintGoalDescriptorHoldDuring& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(hold-during " << parse_text(node.number_left, options) << " " + << parse_text(node.number_right, options) << " " + << parse_text(node.goal_descriptor, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::ConstraintGoalDescriptorHoldAfter& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(hold-after " << parse_text(node.number, options) << " " + << parse_text(node.goal_descriptor, options) << ")"; + return ss.str(); + } + + + std::string parse_text(const domain::ast::PreferenceName& node, const FormattingOptions& options) { + return parse_text(node.name, options); + } + + std::string parse_text(const domain::ast::PreconditionGoalDescriptor& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + std::string parse_text(const domain::ast::PreconditionGoalDescriptorSimple& node, const FormattingOptions& options) { + return parse_text(node.goal_descriptor, options); + } + + std::string parse_text(const domain::ast::PreconditionGoalDescriptorAnd& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(and " << parse_text(node.precondition_goal_descriptors, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::PreconditionGoalDescriptorPreference& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(preference " << parse_text(node.preference_name, options) << " " + << parse_text(node.goal_descriptor, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::PreconditionGoalDescriptorForall& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(forall " << parse_text(node.typed_list_of_variables, options) << " " + << parse_text(node.precondition_goal_descriptor, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::AssignOperatorAssign&, const FormattingOptions&) { return "assign"; } + std::string parse_text(const domain::ast::AssignOperatorScaleUp&, const FormattingOptions&) { return "scale-up"; } + std::string parse_text(const domain::ast::AssignOperatorScaleDown&, const FormattingOptions&) { return "scale-down"; } + std::string parse_text(const domain::ast::AssignOperatorIncrease&, const FormattingOptions&) { return "increase"; } + std::string parse_text(const domain::ast::AssignOperatorDecrease&, const FormattingOptions&) { return "decrease"; } + std::string parse_text(const domain::ast::AssignOperator& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + std::string parse_text(const domain::ast::Effect& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + std::string parse_text(const domain::ast::EffectProductionLiteral& node, const FormattingOptions& options) { + return parse_text(node.literal, options); + } + + std::string parse_text(const domain::ast::EffectProductionNumericFluentTotalCost& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(" << parse_text(node.assign_operator_increase, options) << " " + << parse_text(node.function_symbol_total_cost, options) << " " + << parse_text(node.numeric_term, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::EffectProductionNumericFluentGeneral& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(" << parse_text(node.assign_operator, options) << " " + << parse_text(node.function_head, options) << " " + << parse_text(node.function_expression, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::EffectProduction& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + std::string parse_text(const domain::ast::EffectConditionalForall& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(forall " << parse_text(node.typed_list_of_variables, options) << " " + << parse_text(node.effect, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::EffectConditionalWhen& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(when " << parse_text(node.goal_descriptor, options) << " " + << parse_text(node.effect, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::EffectConditional& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + + std::string parse_text(const domain::ast::ActionSymbol& node, const FormattingOptions& options) { + return parse_text(node.name, options); + } + + std::string parse_text(const domain::ast::ActionBody& node, const FormattingOptions& options) { + std::stringstream ss; + if (node.precondition_goal_descriptor.has_value()) { + ss << std::string(options.indent, ' ') << ":precondition " << parse_text(node.precondition_goal_descriptor.value(), options) << "\n"; + } + if (node.effect.has_value()) { + ss << std::string(options.indent, ' ') << ":effect " << parse_text(node.effect.value(), options); + } + return ss.str(); + } + + + std::string parse_text(const domain::ast::Action& node, const FormattingOptions& options) { + std::stringstream ss; + ss << std::string(options.indent, ' ') + << "(action " + << parse_text(node.action_symbol, options) << "\n"; + FormattingOptions nested_options{options.indent + options.add_indent, options.add_indent}; + ss << std::string(nested_options.indent, ' ') + << ":parameters (" + << parse_text(node.typed_list_of_variables, nested_options) << ")\n" + << parse_text(node.action_body, nested_options) << "\n"; + ss << std::string(options.indent, ' ') << ")"; + + return ss.str(); + } + + std::string parse_text(const domain::ast::DerivedPredicate& node, const FormattingOptions& options) { + std::stringstream ss; + ss << std::string(options.indent, ' ') << "(:derived " + << parse_text(node.typed_list_of_variables, options) << " " + << parse_text(node.goal_descriptor, options) << ")"; + return ss.str(); + } + + + + std::string parse_text(const domain::ast::DomainName& node, const FormattingOptions& options) { + stringstream ss; + ss << "(domain " << parse_text(node.name, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::Requirements& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(:requirements "; + for (size_t i = 0; i < node.requirements.size(); ++i) { + if (i != 0) ss << " "; + ss << parse_text(node.requirements[i], options); + } + ss << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::Types& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(:types " << parse_text(node.typed_list_of_names, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::Constants& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(:constants " << parse_text(node.typed_list_of_names, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::Predicates& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(:predicates " << parse_text(node.atomic_formula_skeletons, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::Functions& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(:functions " << parse_text(node.function_types_list_of_atomic_function_skeletons, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::Constraints& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(:constraints " << parse_text(node.constraint_goal_descriptor, options) << ")"; + return ss.str(); + } + + std::string parse_text(const domain::ast::Structure& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + + std::string parse_text(const domain::ast::Domain& node, const FormattingOptions& options) { + std::stringstream ss; + ss << string(options.indent, ' ') << "(define " << parse_text(node.domain_name, options) << "\n"; + auto nested_options = FormattingOptions{options.indent + options.add_indent, options.add_indent}; + if (node.requirements.has_value()) { + ss << string(nested_options.indent, ' ') << parse_text(node.requirements.value(), nested_options) << "\n"; + } + if (node.types.has_value()) { + ss << string(nested_options.indent, ' ') << parse_text(node.types.value(), nested_options) << "\n"; + } + if (node.constants.has_value()) { + ss << string(nested_options.indent, ' ') << parse_text(node.constants.value(), nested_options) << "\n"; + } + if (node.predicates.has_value()) { + ss << string(nested_options.indent, ' ') << parse_text(node.predicates.value(), nested_options) << "\n"; + } + if (node.functions.has_value()) { + ss << string(nested_options.indent, ' ') << parse_text(node.functions.value(), nested_options) << "\n"; + } + if (node.constraints.has_value()) { + ss << string(nested_options.indent, ' ') << parse_text(node.constraints.value(), nested_options) << "\n"; + } + for (size_t i = 0; i < node.structures.size(); ++i) { + ss << string(nested_options.indent, ' ') << parse_text(node.structures[i], nested_options) << "\n"; + } + ss << std::string(options.indent, ' ') << ")"; + return ss.str(); + } + + + template + inline std::string parse_text(const std::vector& nodes, const FormattingOptions& options) + { + std::stringstream ss; + for (size_t i = 0; i < nodes.size(); ++i) + { + if (i != 0) + ss << " "; + ss << parse_text(nodes[i], options); + } + return ss.str(); + } +} diff --git a/src/domain/parser.cpp b/src/domain/parser.cpp new file mode 100644 index 00000000..55279b60 --- /dev/null +++ b/src/domain/parser.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../include/loki/domain/parser.hpp" + +#include "../../include/loki/common/memory.hpp" +#include "../../include/loki/common/ast/error_reporting.hpp" +#include "../../include/loki/common/pddl/error_reporting.hpp" +#include "../../include/loki/common/pddl/context.hpp" +#include "../../include/loki/common/filesystem.hpp" +#include "../../include/loki/common/ast/parser_wrapper.hpp" +#include "../../include/loki/common/exceptions.hpp" +#include "../../include/loki/domain/ast/parser.hpp" +#include "../../include/loki/domain/ast/ast.hpp" +#include "../../include/loki/domain/pddl/parser.hpp" + +#include +#include +#include + + +namespace loki { + +DomainParser::DomainParser(const fs::path& file_path) + : m_file_path(file_path) + , m_source(loki::read_file(file_path)) + , m_position_cache(nullptr) + , m_scopes(nullptr) { + const auto start = std::chrono::high_resolution_clock::now(); + std::cout << "Started parsing domain file: " << file_path << std::endl; + + /* Parse the AST */ + auto node = domain::ast::Domain(); + auto x3_error_handler = X3ErrorHandler(m_source.begin(), m_source.end(), file_path); + bool success = parse_ast(m_source, domain::domain(), node, x3_error_handler.get_error_handler()); + if (!success) { + throw SyntaxParserError("", x3_error_handler.get_error_stream().str()); + } + + /* Parse the domain to PDDL */ + // Initialize the context + auto composite_factories = CompositeOfPDDLFactories{ + m_factories.requirements, + m_factories.types, + m_factories.variables, + m_factories.terms, + m_factories.objects, // use factory shared between domain and problem to include constants in indexing 0,1,... + m_factories.domain_atoms, // use domain specific factory + m_factories.domain_literals, // use domain specific factory + m_factories.parameters, + m_factories.predicates, + m_factories.function_expressions, + m_factories.functions, + m_factories.function_skeletons, + m_factories.conditions, + m_factories.effects, + m_factories.actions, + m_factories.derived_predicates, + m_factories.optimization_metrics, + m_factories.numeric_fluents, + m_factories.domains, + m_factories.problems + }; + + m_position_cache = std::make_unique(x3_error_handler, file_path); + m_scopes = std::make_unique(m_position_cache->get_error_handler()); + + auto context = Context(composite_factories, *m_position_cache, *m_scopes); + // Initialize global scope + context.scopes.open_scope(); + + // Create base types. + const auto base_type_object = context.factories.types.get_or_create("object"); + const auto base_type_number = context.factories.types.get_or_create("number"); + context.scopes.insert("object", base_type_object, {}); + context.scopes.insert("number", base_type_number, {}); + + // Create equal predicate with name "=" and two parameters "?left_arg" and "?right_arg" + const auto binary_parameterlist = pddl::ParameterList{ + context.factories.parameters.get_or_create( + context.factories.variables.get_or_create("?left_arg"), + pddl::TypeList{base_type_object}), + context.factories.parameters.get_or_create( + context.factories.variables.get_or_create("?right_arg"), + pddl::TypeList{base_type_object}) + + }; + const auto equal_predicate = context.factories.predicates.get_or_create("=", binary_parameterlist); + context.scopes.insert("=", equal_predicate, {}); + + m_domain = parse(node, context); + + // Only the global scope remains + assert(context.scopes.get_stack().size() == 1); + + const auto [vm_usage, resident_set] = process_mem_usage(); + const auto stop = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(stop - start); + std::cout << "Finished parsing after " << duration.count() << " milliseconds." << std::endl; + std::cout << "Peak virtual memory: " << vm_usage << " KB." << std::endl; + std::cout << "Peak resident set size: " << resident_set << " KB." << std::endl; +} + +CollectionOfPDDLFactories& DomainParser::get_factories() { + return m_factories; +} + +const PDDLPositionCache& DomainParser::get_position_cache() const { + return *m_position_cache; +} + +const pddl::Domain& DomainParser::get_domain() const { + return m_domain; +} + +} \ No newline at end of file diff --git a/src/domain/pddl/action.cpp b/src/domain/pddl/action.cpp new file mode 100644 index 00000000..511ccb20 --- /dev/null +++ b/src/domain/pddl/action.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/domain/pddl/action.hpp" + +#include "../../../include/loki/domain/pddl/parameter.hpp" +#include "../../../include/loki/common/hash.hpp" +#include "../../../include/loki/common/collections.hpp" +#include "../../../include/loki/common/pddl/visitors.hpp" + + +namespace loki::pddl { +ActionImpl::ActionImpl(int identifier, std::string name, ParameterList parameters, std::optional condition, std::optional effect) + : Base(identifier) + , m_name(std::move(name)) + , m_parameters(std::move(parameters)) + , m_condition(std::move(condition)) + , m_effect(std::move(effect)) +{ +} + +bool ActionImpl::is_structurally_equivalent_to_impl(const ActionImpl& other) const { + return (m_name == other.m_name) + && (get_sorted_vector(m_parameters) == get_sorted_vector(other.m_parameters)) + && (*m_condition == *other.m_condition) + && (*m_effect == *other.m_effect); +} + +size_t ActionImpl::hash_impl() const { + return hash_combine( + m_name, + hash_container(m_parameters), + *m_condition, + *m_effect); +} + +void ActionImpl::str_impl(std::ostringstream& out, const FormattingOptions& options) const { + auto nested_options = FormattingOptions{options.indent + options.add_indent, options.add_indent}; + out << std::string(options.indent, ' ') << "(action " << m_name << "\n" + << std::string(nested_options.indent, ' ') << ":parameters ("; + for (size_t i = 0; i < m_parameters.size(); ++i) { + if (i != 0) out << " "; + out << *m_parameters[i]; + } + out << ")"; + out << "\n"; + out << std::string(nested_options.indent, ' ') << ":conditions "; + if (m_condition.has_value()) std::visit(StringifyVisitor(out, options), *m_condition.value()); + else out << "()" ; + + out << "\n"; + out << std::string(nested_options.indent, ' ') << ":effects "; + if (m_effect.has_value()) std::visit(StringifyVisitor(out, options), *m_effect.value()); + else out << "()" ; + + out << ")\n"; +} + +const std::string& ActionImpl::get_name() const { + return m_name; +} + +const ParameterList& ActionImpl::get_parameters() const { + return m_parameters; +} + +const std::optional& ActionImpl::get_condition() const { + return m_condition; +} + +const std::optional& ActionImpl::get_effect() const { + return m_effect; +} + +} + +namespace std { + bool less::operator()( + const loki::pddl::Action& left_action, + const loki::pddl::Action& right_action) const { + return *left_action < *right_action; + } + + std::size_t hash::operator()(const loki::pddl::ActionImpl& action) const { + return action.hash_impl(); + } +} diff --git a/src/domain/pddl/atom.cpp b/src/domain/pddl/atom.cpp new file mode 100644 index 00000000..be7ab801 --- /dev/null +++ b/src/domain/pddl/atom.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/domain/pddl/atom.hpp" + +#include "../../../include/loki/domain/pddl/predicate.hpp" +#include "../../../include/loki/domain/pddl/term.hpp" +#include "../../../include/loki/common/hash.hpp" +#include "../../../include/loki/common/collections.hpp" +#include "../../../include/loki/common/pddl/visitors.hpp" + + +namespace loki::pddl { +AtomImpl::AtomImpl(int identifier, Predicate predicate, TermList terms) + : Base(identifier) + , m_predicate(std::move(predicate)) + , m_terms(std::move(terms)) +{ +} + +bool AtomImpl::is_structurally_equivalent_to_impl(const AtomImpl& other) const { + return (m_predicate == other.m_predicate) + && (m_terms == other.m_terms); +} + +size_t AtomImpl::hash_impl() const { + return hash_combine(m_predicate, hash_container(m_terms)); +} + + +void AtomImpl::str_impl(std::ostringstream& out, const FormattingOptions& options) const { + out << "(" << m_predicate->get_name(); + for (size_t i = 0; i < m_terms.size(); ++i) { + out << " "; + std::visit(StringifyVisitor(out, options), *m_terms[i]); + } + out << ")"; +} + +const Predicate& AtomImpl::get_predicate() const { + return m_predicate; +} + +const TermList& AtomImpl::get_terms() const { + return m_terms; +} + +} + + +namespace std { + bool less::operator()( + const loki::pddl::Atom& left_atom, + const loki::pddl::Atom& right_atom) const { + return *left_atom < *right_atom; + } + + std::size_t hash::operator()(const loki::pddl::AtomImpl& atom) const { + return atom.hash_impl(); + } +} diff --git a/src/domain/pddl/conditions.cpp b/src/domain/pddl/conditions.cpp new file mode 100644 index 00000000..4b05f2e9 --- /dev/null +++ b/src/domain/pddl/conditions.cpp @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/domain/pddl/conditions.hpp" + +#include "../../../include/loki/domain/pddl/literal.hpp" +#include "../../../include/loki/domain/pddl/parameter.hpp" +#include "../../../include/loki/common/hash.hpp" +#include "../../../include/loki/common/collections.hpp" +#include "../../../include/loki/common/pddl/visitors.hpp" + + +namespace loki::pddl { + +/* Literal */ +ConditionLiteralImpl::ConditionLiteralImpl(int identifier, Literal literal) + : Base(identifier) + , m_literal(std::move(literal)) { } + +bool ConditionLiteralImpl::is_structurally_equivalent_to_impl(const ConditionLiteralImpl& other) const { + if (this != &other) { + return m_literal == other.m_literal; + } + return true; +} + +size_t ConditionLiteralImpl::hash_impl() const { + return std::hash()(m_literal); +} + +void ConditionLiteralImpl::str_impl(std::ostringstream& out, const FormattingOptions& /*options*/) const { + out << *m_literal; +} + +const Literal& ConditionLiteralImpl::get_literal() const { + return m_literal; +} + + +/* And */ +ConditionAndImpl::ConditionAndImpl(int identifier, ConditionList conditions) + : Base(identifier) + , m_conditions(std::move(conditions)) { } + +bool ConditionAndImpl::is_structurally_equivalent_to_impl(const ConditionAndImpl& other) const { + if (this != &other) { + return get_sorted_vector(m_conditions) == get_sorted_vector(other.m_conditions); + } + return true; +} + +size_t ConditionAndImpl::hash_impl() const { + return hash_container(get_sorted_vector(m_conditions)); +} + +void ConditionAndImpl::str_impl(std::ostringstream& out, const FormattingOptions& options) const { + out << "(and "; + for (size_t i = 0; i < m_conditions.size(); ++i) { + if (i != 0) out << " "; + std::visit(StringifyVisitor(out, options), *m_conditions[i]); + } + out << ")"; +} + +const ConditionList& ConditionAndImpl::get_conditions() const { + return m_conditions; +} + + +/* Or */ +ConditionOrImpl::ConditionOrImpl(int identifier, ConditionList conditions) + : Base(identifier) + , m_conditions(std::move(conditions)) { } + +bool ConditionOrImpl::is_structurally_equivalent_to_impl(const ConditionOrImpl& other) const { + if (this != &other) { + return get_sorted_vector(m_conditions) == get_sorted_vector(other.m_conditions); + } + return true; +} + +size_t ConditionOrImpl::hash_impl() const { + return hash_container(get_sorted_vector(m_conditions)); +} + +void ConditionOrImpl::str_impl(std::ostringstream& out, const FormattingOptions& options) const { + out << "(or "; + for (size_t i = 0; i < m_conditions.size(); ++i) { + if (i != 0) out << " "; + std::visit(StringifyVisitor(out, options), *m_conditions[i]); + } + out << ")"; +} + +const ConditionList& ConditionOrImpl::get_conditions() const { + return m_conditions; +} + + +/* Not */ +ConditionNotImpl::ConditionNotImpl(int identifier, Condition condition) + : Base(identifier) + , m_condition(std::move(condition)) { } + +bool ConditionNotImpl::is_structurally_equivalent_to_impl(const ConditionNotImpl& other) const { + if (this != &other) { + return m_condition == other.m_condition; + } + return true; +} + +size_t ConditionNotImpl::hash_impl() const { + return hash_combine(m_condition); +} + +void ConditionNotImpl::str_impl(std::ostringstream& out, const FormattingOptions& options) const { + out << "(not "; + std::visit(StringifyVisitor(out, options), *m_condition); + out << ")"; +} + +const Condition& ConditionNotImpl::get_condition() const { + return m_condition; +} + + +/* Imply */ +ConditionImplyImpl::ConditionImplyImpl(int identifier, Condition condition_left, Condition condition_right) + : Base(identifier), m_condition_left(std::move(condition_left)), m_condition_right(std::move(condition_right)) { } + +bool ConditionImplyImpl::is_structurally_equivalent_to_impl(const ConditionImplyImpl& other) const { + if (this != &other) { + return (m_condition_left == other.m_condition_left) + && (m_condition_right == other.m_condition_right); + } + return true; +} + +size_t ConditionImplyImpl::hash_impl() const { + return hash_combine(m_condition_left, m_condition_right); +} + +void ConditionImplyImpl::str_impl(std::ostringstream& out, const FormattingOptions& options) const { + out << "(imply "; + std::visit(StringifyVisitor(out, options), *m_condition_left); + out << " "; + std::visit(StringifyVisitor(out, options), *m_condition_right); + out << ")"; +} + +const Condition& ConditionImplyImpl::get_condition_left() const { + return m_condition_left; +} + +const Condition& ConditionImplyImpl::get_condition_right() const { + return m_condition_right; +} + + +/* Exists */ +ConditionExistsImpl::ConditionExistsImpl(int identifier, ParameterList parameters, Condition condition) + : Base(identifier), m_parameters(std::move(parameters)), m_condition(std::move(condition)) { } + +bool ConditionExistsImpl::is_structurally_equivalent_to_impl(const ConditionExistsImpl& other) const { + if (this != &other) { + return (m_parameters == other.m_parameters) + && (m_condition == other.m_condition); + } + return true; +} + +size_t ConditionExistsImpl::hash_impl() const { + return hash_combine(hash_container(m_parameters), m_condition); +} + +void ConditionExistsImpl::str_impl(std::ostringstream& out, const FormattingOptions& options) const { + out << "(exists ("; + for (size_t i = 0; i < m_parameters.size(); ++i) { + if (i != 0) out << " "; + out << *m_parameters[i]; + } + out << ") "; + std::visit(StringifyVisitor(out, options), *m_condition); + out << ")"; +} + +const ParameterList& ConditionExistsImpl::get_parameters() const { + return m_parameters; +} + +const Condition& ConditionExistsImpl::get_condition() const { + return m_condition; +} + + +/* Forall */ +ConditionForallImpl::ConditionForallImpl(int identifier, ParameterList parameters, Condition condition) + : Base(identifier), m_parameters(std::move(parameters)), m_condition(std::move(condition)) { } + +bool ConditionForallImpl::is_structurally_equivalent_to_impl(const ConditionForallImpl& other) const { + if (this != &other) { + return (m_parameters == other.m_parameters) + && (m_condition == other.m_condition); + } + return true; +} + +size_t ConditionForallImpl::hash_impl() const { + return hash_combine(hash_container(m_parameters), m_condition); +} + +void ConditionForallImpl::str_impl(std::ostringstream& out, const FormattingOptions& options) const { + out << "(forall ("; + for (size_t i = 0; i < m_parameters.size(); ++i) { + if (i != 0) out << " "; + out << *m_parameters[i]; + } + out << ") "; + std::visit(StringifyVisitor(out, options), *m_condition); + out << ")"; +} + +const ParameterList& ConditionForallImpl::get_parameters() const { + return m_parameters; +} + +const Condition& ConditionForallImpl::get_condition() const { + return m_condition; +} + +} + + +namespace std { + bool less::operator()( + const loki::pddl::Condition& left_condition, + const loki::pddl::Condition& right_condition) const { + return std::visit(loki::pddl::LessComparatorVisitor(), *left_condition, *right_condition); + } + + std::size_t hash::operator()(const loki::pddl::ConditionLiteralImpl& condition) const { + return condition.hash_impl(); + } + + std::size_t hash::operator()(const loki::pddl::ConditionAndImpl& condition) const { + return condition.hash_impl(); + } + + std::size_t hash::operator()(const loki::pddl::ConditionOrImpl& condition) const { + return condition.hash_impl(); + } + + std::size_t hash::operator()(const loki::pddl::ConditionNotImpl& condition) const { + return condition.hash_impl(); + } + + std::size_t hash::operator()(const loki::pddl::ConditionImplyImpl& condition) const { + return condition.hash_impl(); + } + + std::size_t hash::operator()(const loki::pddl::ConditionExistsImpl& condition) const { + return condition.hash_impl(); + } + + std::size_t hash::operator()(const loki::pddl::ConditionForallImpl& condition) const { + return condition.hash_impl(); + } +} diff --git a/src/domain/pddl/derived_predicate.cpp b/src/domain/pddl/derived_predicate.cpp new file mode 100644 index 00000000..23b711b0 --- /dev/null +++ b/src/domain/pddl/derived_predicate.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/domain/pddl/derived_predicate.hpp" +#include "../../../include/loki/common/hash.hpp" +#include "../../../include/loki/common/collections.hpp" + + +namespace loki::pddl { +DerivedPredicateImpl::DerivedPredicateImpl(int identifier, ParameterList parameters, Condition condition) + : Base(identifier) + , m_parameters(std::move(parameters)) + , m_condition(std::move(condition)) +{ +} + +bool DerivedPredicateImpl::is_structurally_equivalent_to_impl(const DerivedPredicateImpl& other) const { + return (get_sorted_vector(m_parameters) == get_sorted_vector(other.m_parameters)) + && (m_condition == other.m_condition); +} + +size_t DerivedPredicateImpl::hash_impl() const { + return hash_combine(hash_container(get_sorted_vector(m_parameters)), m_condition); +} + +void DerivedPredicateImpl::str_impl(std::ostringstream& out, const FormattingOptions& /*options*/) const { + out << "TODO"; +} + +const ParameterList& DerivedPredicateImpl::get_parameters() const { + return m_parameters; +} + +const Condition& DerivedPredicateImpl::get_condition() const { + return m_condition; +} + +} + + +namespace std { + bool less::operator()( + const loki::pddl::DerivedPredicate& left_predicate, + const loki::pddl::DerivedPredicate& right_predicate) const { + return *left_predicate < *right_predicate; + } + + std::size_t hash::operator()(const loki::pddl::DerivedPredicateImpl& action) const { + return action.hash_impl(); + } +} diff --git a/src/domain/pddl/domain.cpp b/src/domain/pddl/domain.cpp new file mode 100644 index 00000000..bf5fbb41 --- /dev/null +++ b/src/domain/pddl/domain.cpp @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/domain/pddl/domain.hpp" + +#include "../../../include/loki/domain/pddl/action.hpp" +#include "../../../include/loki/domain/pddl/function_skeleton.hpp" +#include "../../../include/loki/domain/pddl/object.hpp" +#include "../../../include/loki/domain/pddl/predicate.hpp" +#include "../../../include/loki/domain/pddl/type.hpp" +#include "../../../include/loki/common/hash.hpp" +#include "../../../include/loki/common/collections.hpp" + +#include + +using namespace std; + + +namespace loki::pddl { +DomainImpl::DomainImpl(int identifier, + std::string name, + Requirements requirements, + TypeList types, + ObjectList constants, + PredicateList predicates, + FunctionSkeletonList functions, + ActionList actions) + : Base(identifier) + , m_name(std::move(name)) + , m_requirements(std::move(requirements)) + , m_types(std::move(types)) + , m_constants(std::move(constants)) + , m_predicates(std::move(predicates)) + , m_functions(std::move(functions)) + , m_actions(std::move(actions)) +{ +} + +bool DomainImpl::is_structurally_equivalent_to_impl(const DomainImpl& other) const { + return (m_name == other.m_name) + && (m_requirements == other.m_requirements) + && (get_sorted_vector(m_types) == get_sorted_vector(other.m_types)) + && (get_sorted_vector(m_constants) == get_sorted_vector(other.m_constants)) + && (get_sorted_vector(m_predicates) == get_sorted_vector(other.m_predicates)) + && (get_sorted_vector(m_functions) == get_sorted_vector(other.m_functions)) + && (get_sorted_vector(m_actions) == get_sorted_vector(other.m_actions)); +} + +size_t DomainImpl::hash_impl() const { + return hash_combine( + m_name, + m_requirements, + hash_container(get_sorted_vector(m_types)), + hash_container(get_sorted_vector(m_constants)), + hash_container(get_sorted_vector(m_predicates)), + hash_container(get_sorted_vector(m_functions)), + hash_container(get_sorted_vector(m_actions))); +} + +void DomainImpl::str_impl(std::ostringstream& out, const FormattingOptions& options) const { + out << string(options.indent, ' ') << "(define (domain " << m_name << ")\n"; + auto nested_options = FormattingOptions{options.indent + options.add_indent, options.add_indent}; + if (!m_requirements->get_requirements().empty()) { + out << string(nested_options.indent, ' ') << m_requirements->str() << "\n"; + } + if (!m_types.empty()) { + out << string(nested_options.indent, ' ') << "(:types "; + std::unordered_map> subtypes_by_parent_types; + for (const auto& type : m_types) { + subtypes_by_parent_types[type->get_bases()].push_back(type); + } + size_t i = 0; + for (const auto& pair : subtypes_by_parent_types) { + if (i != 0) out << "\n" << string(nested_options.indent, ' '); + const auto& sub_types = pair.second; + for (size_t i = 0; i < sub_types.size(); ++i) { + if (i != 0) out << " "; + out << *sub_types[i]; + } + out << " - "; + const auto& types = pair.first; + for (size_t i = 0; i < types.size(); ++i) { + if (i != 0) out << " "; + out << *types[i]; + } + ++i; + } + out << ")\n"; + } + if (!m_constants.empty()) { + out << string(nested_options.indent, ' ') << "(:constants "; + std::unordered_map> constants_by_types; + for (const auto& constant : m_constants) { + constants_by_types[constant->get_bases()].push_back(constant); + } + size_t i = 0; + for (const auto& pair : constants_by_types) { + if (i != 0) out << "\n" << string(nested_options.indent, ' '); + const auto& constants = pair.second; + for (size_t i = 0; i < constants.size(); ++i) { + if (i != 0) out << " "; + out << *constants[i]; + } + if (m_requirements->test(RequirementEnum::TYPING)) { + out << " - "; + const auto& types = pair.first; + for (size_t i = 0; i < types.size(); ++i) { + if (i != 0) out << " "; + out << *types[i]; + } + } + ++i; + } + out << ")\n"; + } + if (!m_predicates.empty()) { + out << string(nested_options.indent, ' ') << "(:predicates "; + for (size_t i = 0; i < m_predicates.size(); ++i) { + if (i != 0) out << " "; + m_predicates[i]->str(out, nested_options, m_requirements->test(RequirementEnum::TYPING)); + } + out << ")\n"; + } + if (!m_functions.empty()) { + out << string(nested_options.indent, ' ') << "(:functions "; + for (size_t i = 0; i < m_functions.size(); ++i) { + if (i != 0) out << " "; + out << *m_functions[i]; + } + } + + /* + if (node.constraints.has_value()) { + ss << string(nested_options.indent, ' ') << parse_text(node.constraints.value(), nested_options) << "\n"; + } + for (size_t i = 0; i < node.structures.size(); ++i) { + ss << string(nested_options.indent, ' ') << parse_text(node.structures[i], nested_options) << "\n"; + } + */ + + for (const auto& action : m_actions) { + action->str(out, nested_options); + } + + out << std::string(options.indent, ' ') << ")"; +} + +const std::string& DomainImpl::get_name() const { + return m_name; +} + +const Requirements& DomainImpl::get_requirements() const { + return m_requirements; +} + +const TypeList& DomainImpl::get_types() const { + return m_types; +} + +const ObjectList& DomainImpl::get_constants() const { + return m_constants; +} + +const PredicateList& DomainImpl::get_predicates() const { + return m_predicates; +} + +const ActionList& DomainImpl::get_actions() const { + return m_actions; +} + +} + +namespace std { + bool less::operator()( + const loki::pddl::Domain& left_domain, + const loki::pddl::Domain& right_domain) const { + return *left_domain < *right_domain; + } + + std::size_t hash::operator()(const loki::pddl::DomainImpl& domain) const { + return domain.hash_impl(); + } +} diff --git a/src/domain/pddl/effects.cpp b/src/domain/pddl/effects.cpp new file mode 100644 index 00000000..1f03c5ff --- /dev/null +++ b/src/domain/pddl/effects.cpp @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/domain/pddl/effects.hpp" + +#include "../../../include/loki/domain/pddl/conditions.hpp" +#include "../../../include/loki/domain/pddl/literal.hpp" +#include "../../../include/loki/domain/pddl/parameter.hpp" +#include "../../../include/loki/domain/pddl/function.hpp" +#include "../../../include/loki/domain/pddl/function_expressions.hpp" +#include "../../../include/loki/common/hash.hpp" +#include "../../../include/loki/common/collections.hpp" +#include "../../../include/loki/common/pddl/visitors.hpp" + +#include + + +namespace loki::pddl { + +std::unordered_map assign_operator_enum_to_string = { + { AssignOperatorEnum::ASSIGN, "assign" }, + { AssignOperatorEnum::SCALE_UP, "scale-up" }, + { AssignOperatorEnum::SCALE_DOWN, "scale-down" }, + { AssignOperatorEnum::INCREASE, "increase" }, + { AssignOperatorEnum::DECREASE, "decrease" }, +}; + +const std::string& to_string(pddl::AssignOperatorEnum assign_operator) { + assert(assign_operator_enum_to_string.count(assign_operator)); + return assign_operator_enum_to_string.at(assign_operator); +} + + +/* Literal */ +EffectLiteralImpl::EffectLiteralImpl(int identifier, Literal literal) + : Base(identifier) + , m_literal(std::move(literal)) { } + +bool EffectLiteralImpl::is_structurally_equivalent_to_impl(const EffectLiteralImpl& other) const { + if (this != &other) { + return m_literal == other.m_literal; + } + return true; +} + +size_t EffectLiteralImpl::hash_impl() const { + return std::hash()(m_literal); +} + +void EffectLiteralImpl::str_impl(std::ostringstream& out, const FormattingOptions& /*options*/) const { + out << *m_literal; +} + +const Literal& EffectLiteralImpl::get_literal() const { + return m_literal; +} + + +EffectAndImpl::EffectAndImpl(int identifier, EffectList effects) + : Base(identifier), m_effects(std::move(effects)) { } + +bool EffectAndImpl::is_structurally_equivalent_to_impl(const EffectAndImpl& other) const { + if (this != &other) { + return get_sorted_vector(m_effects) == get_sorted_vector(other.m_effects); + } + return true; +} + +size_t EffectAndImpl::hash_impl() const { + return hash_container(get_sorted_vector(m_effects)); +} + +void EffectAndImpl::str_impl(std::ostringstream& out, const FormattingOptions& options) const { + out << "(and "; + for (size_t i = 0; i < m_effects.size(); ++i) { + if (i != 0) out << " "; + std::visit(StringifyVisitor(out, options), *m_effects[i]); + } + out << ")"; +} + +const EffectList& EffectAndImpl::get_effects() const { + return m_effects; +} + + +/* EffectNumeric */ +EffectNumericImpl::EffectNumericImpl(int identifier, AssignOperatorEnum assign_operator, Function function, FunctionExpression function_expression) + : Base(identifier) + , m_assign_operator(assign_operator) + , m_function(std::move(function)) + , m_function_expression(std::move(function_expression)) { } + +bool EffectNumericImpl::is_structurally_equivalent_to_impl(const EffectNumericImpl& other) const { + if (this != &other) { + return (m_assign_operator == other.m_assign_operator) + && (m_function == other.m_function) + && (m_function_expression == other.m_function_expression); + } + return true; +} + +size_t EffectNumericImpl::hash_impl() const { + return hash_combine(m_assign_operator, m_function, m_function_expression); +} + +void EffectNumericImpl::str_impl(std::ostringstream& out, const FormattingOptions& options) const { + out << "(" << to_string(m_assign_operator) << " " << *m_function << " "; + std::visit(StringifyVisitor(out, options), *m_function_expression); + out << ")"; +} + +AssignOperatorEnum EffectNumericImpl::get_assign_operator() const { + return m_assign_operator; +} + +const Function& EffectNumericImpl::get_function() const { + return m_function; +} + +const FunctionExpression& EffectNumericImpl::get_function_expression() const { + return m_function_expression; +} + + +/* ConditionalForall */ +EffectConditionalForallImpl::EffectConditionalForallImpl(int identifier, ParameterList parameters, Effect effect) + : Base(identifier), m_parameters(std::move(parameters)), m_effect(std::move(effect)) { } + +bool EffectConditionalForallImpl::is_structurally_equivalent_to_impl(const EffectConditionalForallImpl& other) const { + if (this != &other) { + return (m_parameters == other.m_parameters) + && (m_effect == other.m_effect); + } + return true; +} + +size_t EffectConditionalForallImpl::hash_impl() const { + return hash_combine(hash_container(m_parameters), m_effect); +} + +void EffectConditionalForallImpl::str_impl(std::ostringstream& out, const FormattingOptions& options) const { + out << "(forall ("; + for (size_t i = 0; i < m_parameters.size(); ++i) { + if (i != 0) out << " "; + out << *m_parameters[i]; + } + out << ") "; + std::visit(StringifyVisitor(out, options), *m_effect); + out << ")"; +} + +const ParameterList& EffectConditionalForallImpl::get_parameters() const { + return m_parameters; +} + +const Effect& EffectConditionalForallImpl::get_effect() const { + return m_effect; +} + + +EffectConditionalWhenImpl::EffectConditionalWhenImpl(int identifier, Condition condition, Effect effect) + : Base(identifier), m_condition(std::move(condition)), m_effect(std::move(effect)) { } + +bool EffectConditionalWhenImpl::is_structurally_equivalent_to_impl(const EffectConditionalWhenImpl& other) const { + if (this != &other) { + return (m_condition == other.m_condition) + && (m_effect == other.m_effect); + } + return true; +} + +size_t EffectConditionalWhenImpl::hash_impl() const { + return hash_combine(m_condition, m_effect); +} + +void EffectConditionalWhenImpl::str_impl(std::ostringstream& out, const FormattingOptions& options) const { + out << "(when "; + std::visit(StringifyVisitor(out, options), *m_condition); + out << " "; + std::visit(StringifyVisitor(out, options), *m_effect); + out << ")"; +} + +const Condition& EffectConditionalWhenImpl::get_condition() const { + return m_condition; +} + +const Effect& EffectConditionalWhenImpl::get_effect() const { + return m_effect; +} + +} + + +namespace std { + bool less::operator()( + const loki::pddl::Effect& left_effect, + const loki::pddl::Effect& right_effect) const { + return *left_effect < *right_effect; + } + + std::size_t hash::operator()(const loki::pddl::EffectLiteralImpl& effect) const { + return effect.hash_impl(); + } + + std::size_t hash::operator()(const loki::pddl::EffectAndImpl& effect) const { + return effect.hash_impl(); + } + + std::size_t hash::operator()(const loki::pddl::EffectNumericImpl& effect) const { + return effect.hash_impl(); + } + + std::size_t hash::operator()(const loki::pddl::EffectConditionalForallImpl& effect) const { + return effect.hash_impl(); + } + + std::size_t hash::operator()(const loki::pddl::EffectConditionalWhenImpl& effect) const { + return effect.hash_impl(); + } +} diff --git a/src/domain/pddl/exceptions.cpp b/src/domain/pddl/exceptions.cpp new file mode 100644 index 00000000..51f37979 --- /dev/null +++ b/src/domain/pddl/exceptions.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/domain/pddl/exceptions.hpp" + +#include "../../../include/loki/domain/pddl/predicate.hpp" +#include "../../../include/loki/domain/pddl/domain.hpp" +#include "../../../include/loki/domain/pddl/function_skeleton.hpp" + + +namespace loki { +/* Type */ +ReservedTypeError::ReservedTypeError(const std::string& name, const std::string& error_handler_output) + : SemanticParserError( + "Unexpected type name \"" + name + "\". It is a reserved type name", error_handler_output) { } + +UnusedTypeError::UnusedTypeError(const std::string& name, const std::string& error_handler_output) + : SemanticParserError( + "The type with name \"" + name + "\" was never referred to.", error_handler_output) { } + +UndefinedTypeError::UndefinedTypeError(const std::string& name, const std::string& error_handler_output) + : SemanticParserError( + "The type with name \"" + name + "\" is undefined.", error_handler_output) { } + +MultiDefinitionTypeError::MultiDefinitionTypeError(const std::string& name, const std::string& error_handler_output) + : SemanticParserError( + "The type with name \"" + name + "\" has already been defined.", error_handler_output) { } + +/* Predicate */ +UnusedPredicateError::UnusedPredicateError(const std::string& name, const std::string& error_handler_output) + : SemanticParserError( + "The predicate with name \"" + name + "\" was never referred to.", error_handler_output) { } + +UndefinedPredicateError::UndefinedPredicateError(const std::string& name, const std::string& error_handler_output) + : SemanticParserError( + "The predicate with name \"" + name + "\" is undefined.", error_handler_output) { } + +MultiDefinitionPredicateError::MultiDefinitionPredicateError(const std::string& name, const std::string& error_handler_output) + : SemanticParserError( + "The predicate with name \"" + name + "\" has already been defined.", error_handler_output) { } + +/* Constant */ +UndefinedConstantError::UndefinedConstantError(const std::string& name, const std::string& error_handler_output) + : SemanticParserError( + "The constant with name \"" + name + "\" is undefined.", error_handler_output) { } + +MultiDefinitionConstantError::MultiDefinitionConstantError(const std::string& name, const std::string& error_handler_output) + : SemanticParserError( + "The constant with name \"" + name + "\" has already been defined.", error_handler_output) { } + +/* Variable */ +UnusedVariableError::UnusedVariableError(const std::string& name, const std::string& error_handler_output) + : SemanticParserError( + "The variable with name \"" + name + "\" was never referred to.", error_handler_output) { } + +UndefinedVariableError::UndefinedVariableError(const std::string& name, const std::string& error_handler_output) + : SemanticParserError( + "The variable with name \"" + name + "\" is not defined in the current scope.", error_handler_output) { } + +MultiDefinitionVariableError::MultiDefinitionVariableError(const std::string& name, const std::string& error_handler_output) + : SemanticParserError( + "The variable with name \"" + name + "\" has already been defined.", error_handler_output) { } + +/* FunctionSkeleton */ +UnusedFunctionSkeletonError::UnusedFunctionSkeletonError(const std::string& name, const std::string& error_handler_output) + : SemanticParserError( + "The function skeleton with name \"" + name + "\" was never referred to.", error_handler_output) { } + +UndefinedFunctionSkeletonError::UndefinedFunctionSkeletonError(const std::string& name, const std::string& error_handler_output) + : SemanticParserError( + "The function skeleton with name \"" + name + "\" is not defined in the current scope.", error_handler_output) { } + +MultiDefinitionFunctionSkeletonError::MultiDefinitionFunctionSkeletonError(const std::string& name, const std::string& error_handler_output) + : SemanticParserError( + "The function skeleton with name \"" + name + "\" has already been defined.", error_handler_output) { } + +/* Requirement */ +UnusedRequirementError::UnusedRequirementError(pddl::RequirementEnum requirement, const std::string& error_handler_output) + : SemanticParserError( + "The requirement with name \"" + to_string(requirement) + "\" was never used.", error_handler_output) { } + +UndefinedRequirementError::UndefinedRequirementError(pddl::RequirementEnum requirement, const std::string& error_handler_output) + : SemanticParserError("Undefined requirement: " + to_string(requirement), error_handler_output) { } + +UnsupportedRequirementError::UnsupportedRequirementError(pddl::RequirementEnum requirement, const std::string& error_handler_output) + : std::runtime_error("Unsupported requirement: " + to_string(requirement) + "\n" + error_handler_output) { } + +/* Compatibility errors */ +MismatchedPredicateTermListError::MismatchedPredicateTermListError( + const pddl::Predicate& predicate, + const pddl::TermList& term_list, + const std::string& error_handler_output) + : SemanticParserError( + "Mismatched number of terms for predicate \"" + + predicate->get_name() + + "\" with sizes " + + std::to_string(predicate->get_parameters().size()) + + "!=" + + std::to_string(term_list.size()) + + ".", + error_handler_output) { } + +MismatchedFunctionSkeletonTermListError::MismatchedFunctionSkeletonTermListError( + const pddl::FunctionSkeleton& function_skeleton, + const pddl::TermList& term_list, + const std::string& error_handler_output) + : SemanticParserError( + "Mismatched number of terms for function skeleton \"" + + function_skeleton->get_name() + + "\" with sizes " + + std::to_string(function_skeleton->get_parameters().size()) + + "!=" + + std::to_string(term_list.size()) + + ".", + error_handler_output) { } + + +} \ No newline at end of file diff --git a/src/domain/pddl/function.cpp b/src/domain/pddl/function.cpp new file mode 100644 index 00000000..303a8814 --- /dev/null +++ b/src/domain/pddl/function.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/domain/pddl/function.hpp" + +#include "../../../include/loki/domain/pddl/function_skeleton.hpp" +#include "../../../include/loki/domain/pddl/term.hpp" +#include "../../../include/loki/common/hash.hpp" +#include "../../../include/loki/common/pddl/visitors.hpp" + + +namespace loki::pddl { +FunctionImpl::FunctionImpl(int identifier, FunctionSkeleton function_skeleton, TermList terms) + : Base(identifier) + , m_function_skeleton(std::move(function_skeleton)) + , m_terms(std::move(terms)) +{ +} + +bool FunctionImpl::is_structurally_equivalent_to_impl(const FunctionImpl& other) const { + return (m_function_skeleton == other.m_function_skeleton) && (m_terms == other.m_terms); +} + +size_t FunctionImpl::hash_impl() const { + return hash_combine(m_function_skeleton, hash_container(m_terms)); +} + +void FunctionImpl::str_impl(std::ostringstream& out, const FormattingOptions& options) const { + if (m_terms.empty()) { + out << "(" << m_function_skeleton->get_name() << ")"; + } else { + out << "(" << m_function_skeleton->get_name() << "("; + for (size_t i = 0; i < m_terms.size(); ++i) { + if (i != 0) out << " "; + std::visit(StringifyVisitor(out, options), *m_terms[i]); + } + out << "))"; + } +} + +const FunctionSkeleton& FunctionImpl::get_function_skeleton() const { + return m_function_skeleton; +} + +const TermList& FunctionImpl::get_terms() const { + return m_terms; +} + +} + +namespace std { + bool less::operator()( + const loki::pddl::Function& left_function, + const loki::pddl::Function& right_function) const { + return *left_function < *right_function; + } + + std::size_t hash::operator()(const loki::pddl::FunctionImpl& function) const { + return function.hash_impl(); + } +} diff --git a/src/domain/pddl/function_expressions.cpp b/src/domain/pddl/function_expressions.cpp new file mode 100644 index 00000000..7b75f13a --- /dev/null +++ b/src/domain/pddl/function_expressions.cpp @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/domain/pddl/function_expressions.hpp" + +#include "../../../include/loki/common/hash.hpp" +#include "../../../include/loki/common/collections.hpp" +#include "../../../include/loki/domain/pddl/function.hpp" +#include "../../../include/loki/common/pddl/visitors.hpp" + +#include + + +namespace loki::pddl { + +std::unordered_map binary_operator_enum_to_string = { + { BinaryOperatorEnum::MUL, "*" }, + { BinaryOperatorEnum::PLUS, "+" }, + { BinaryOperatorEnum::MINUS, "-" }, + { BinaryOperatorEnum::DIV, "/" }, +}; + +const std::string& to_string(pddl::BinaryOperatorEnum binary_operator) { + assert(binary_operator_enum_to_string.count(binary_operator)); + return binary_operator_enum_to_string.at(binary_operator); +} + + +std::unordered_map multi_operator_enum_to_string = { + { MultiOperatorEnum::MUL, "*" }, + { MultiOperatorEnum::PLUS, "+" }, +}; + +const std::string& to_string(pddl::MultiOperatorEnum multi_operator) { + assert(multi_operator_enum_to_string.count(multi_operator)); + return multi_operator_enum_to_string.at(multi_operator); +} + + +/* FunctionExpressionNumber */ +FunctionExpressionNumberImpl::FunctionExpressionNumberImpl(int identifier, double number) + : Base(identifier), m_number(number) { } + +bool FunctionExpressionNumberImpl::is_structurally_equivalent_to_impl(const FunctionExpressionNumberImpl& other) const { + if (this != &other) { + return m_number == other.m_number; + } + return true; +} + +size_t FunctionExpressionNumberImpl::hash_impl() const { + return std::hash()(m_number); +} + +void FunctionExpressionNumberImpl::str_impl(std::ostringstream& out, const FormattingOptions& /*options*/) const { + out << m_number; +} + +double FunctionExpressionNumberImpl::get_number() const { + return m_number; +} + + +/* FunctionExpressionBinaryOperator */ +FunctionExpressionBinaryOperatorImpl::FunctionExpressionBinaryOperatorImpl(int identifier, + BinaryOperatorEnum binary_operator, + FunctionExpression left_function_expression, + FunctionExpression right_function_expression) + : Base(identifier) + , m_binary_operator(binary_operator) + , m_left_function_expression(std::move(left_function_expression)) + , m_right_function_expression(std::move(right_function_expression)) { } + +bool FunctionExpressionBinaryOperatorImpl::is_structurally_equivalent_to_impl(const FunctionExpressionBinaryOperatorImpl& other) const { + if (this != &other) { + return (m_binary_operator == other.m_binary_operator) + && (m_left_function_expression == other.m_left_function_expression) + && (m_right_function_expression == other.m_right_function_expression); + } + return true; +} + +size_t FunctionExpressionBinaryOperatorImpl::hash_impl() const { + return hash_combine(m_binary_operator, m_left_function_expression, m_right_function_expression); +} + +void FunctionExpressionBinaryOperatorImpl::str_impl(std::ostringstream& out, const FormattingOptions& options) const { + out << "(" << to_string(m_binary_operator) << " "; + std::visit(StringifyVisitor(out, options), *m_left_function_expression); + out << " "; + std::visit(StringifyVisitor(out, options), *m_right_function_expression); + out << ")"; +} + +BinaryOperatorEnum FunctionExpressionBinaryOperatorImpl::get_binary_operator() const { + return m_binary_operator; +} + +const FunctionExpression& FunctionExpressionBinaryOperatorImpl::get_left_function_expression() const { + return m_left_function_expression; +} + +const FunctionExpression& FunctionExpressionBinaryOperatorImpl::get_right_function_expression() const { + return m_right_function_expression; +} + + +/* FunctionExpressionMultiOperator */ +FunctionExpressionMultiOperatorImpl::FunctionExpressionMultiOperatorImpl(int identifier, + MultiOperatorEnum multi_operator, + FunctionExpressionList function_expressions) + : Base(identifier), m_multi_operator(multi_operator), m_function_expressions(function_expressions) { } + +bool FunctionExpressionMultiOperatorImpl::is_structurally_equivalent_to_impl(const FunctionExpressionMultiOperatorImpl& other) const { + if (this != &other) { + return (m_multi_operator == other.m_multi_operator) + && (get_sorted_vector(m_function_expressions) == get_sorted_vector(other.m_function_expressions)); + } + return true; +} + +size_t FunctionExpressionMultiOperatorImpl::hash_impl() const { + return hash_combine(m_multi_operator, hash_container(get_sorted_vector(m_function_expressions))); +} + +void FunctionExpressionMultiOperatorImpl::str_impl(std::ostringstream& out, const FormattingOptions& options) const { + out << "(" << to_string(m_multi_operator); + assert(!m_function_expressions.empty()); + for (const auto& function_expression : m_function_expressions) { + out << " "; + std::visit(StringifyVisitor(out, options), *function_expression); + } + out << ")"; +} + +MultiOperatorEnum FunctionExpressionMultiOperatorImpl::get_multi_operator() const{ + return m_multi_operator; +} + +const FunctionExpressionList& FunctionExpressionMultiOperatorImpl::get_function_expressions() const { + return m_function_expressions; +} + + +/* FunctionExpressionMinus */ +FunctionExpressionMinusImpl::FunctionExpressionMinusImpl(int identifier, FunctionExpression function_expression) + : Base(identifier), m_function_expression(std::move(function_expression)) { } + +bool FunctionExpressionMinusImpl::is_structurally_equivalent_to_impl(const FunctionExpressionMinusImpl& other) const { + if (this != &other) { + return m_function_expression == other.m_function_expression; + } + return true; +} + +size_t FunctionExpressionMinusImpl::hash_impl() const { + return hash_combine(m_function_expression); +} + +void FunctionExpressionMinusImpl::str_impl(std::ostringstream& out, const FormattingOptions& /*options*/) const { + out << "(- " << m_function_expression << ")"; +} + +const FunctionExpression& FunctionExpressionMinusImpl::get_function_expression() const { + return m_function_expression; +} + + +/* FunctionExpressionFunction */ +FunctionExpressionFunctionImpl::FunctionExpressionFunctionImpl(int identifier, Function function) + : Base(identifier), m_function(std::move(function)) { } + +bool FunctionExpressionFunctionImpl::is_structurally_equivalent_to_impl(const FunctionExpressionFunctionImpl& other) const { + if (this != &other) { + return m_function == other.m_function; + } + return true; +} + +size_t FunctionExpressionFunctionImpl::hash_impl() const { + return hash_combine(m_function); +} + +void FunctionExpressionFunctionImpl::str_impl(std::ostringstream& out, const FormattingOptions& /*options*/) const { + out << *m_function; +} + +const Function& FunctionExpressionFunctionImpl::get_function() const { + return m_function; +} + +} + + +namespace std { + bool less::operator()( + const loki::pddl::FunctionExpression& left_function_expression, + const loki::pddl::FunctionExpression& right_function_expression) const { + return *left_function_expression < *right_function_expression; + } + + std::size_t hash::operator()(const loki::pddl::FunctionExpressionNumberImpl& function_expression) const { + return function_expression.hash_impl(); + } + + std::size_t hash::operator()(const loki::pddl::FunctionExpressionBinaryOperatorImpl& function_expression) const { + return function_expression.hash_impl(); + } + + std::size_t hash::operator()(const loki::pddl::FunctionExpressionMultiOperatorImpl& function_expression) const { + return function_expression.hash_impl(); + } + + std::size_t hash::operator()(const loki::pddl::FunctionExpressionMinusImpl& function_expression) const { + return function_expression.hash_impl(); + } + + std::size_t hash::operator()(const loki::pddl::FunctionExpressionFunctionImpl& function_expression) const { + return function_expression.hash_impl(); + } +} diff --git a/src/domain/pddl/function_skeleton.cpp b/src/domain/pddl/function_skeleton.cpp new file mode 100644 index 00000000..37af97f9 --- /dev/null +++ b/src/domain/pddl/function_skeleton.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/domain/pddl/function_skeleton.hpp" + +#include "../../../include/loki/domain/pddl/parameter.hpp" +#include "../../../include/loki/common/hash.hpp" + + +namespace loki::pddl { +FunctionSkeletonImpl::FunctionSkeletonImpl(int identifier, std::string name, ParameterList parameters, Type type) + : Base(identifier) + , m_name(std::move(name)) + , m_parameters(std::move(parameters)) + , m_type(std::move(type)) +{ +} + +bool FunctionSkeletonImpl::is_structurally_equivalent_to_impl(const FunctionSkeletonImpl& other) const { + return (m_name == other.m_name) && (m_parameters == other.m_parameters) && (m_type == other.m_type); +} + +size_t FunctionSkeletonImpl::hash_impl() const { + return hash_combine(m_name, hash_container(m_parameters), m_type); +} + +void FunctionSkeletonImpl::str_impl(std::ostringstream& out, const FormattingOptions& options) const { + str(out, options, true); +} + +void FunctionSkeletonImpl::str(std::ostringstream& out, const FormattingOptions& options, bool typing_enabled) const { + out << "(" << m_name; + for (size_t i = 0; i < m_parameters.size(); ++i) { + out << " "; + m_parameters[i]->str(out, options, typing_enabled); + } + out << ")"; +} + +const std::string& FunctionSkeletonImpl::get_name() const { + return m_name; +} + +const ParameterList& FunctionSkeletonImpl::get_parameters() const { + return m_parameters; +} + +const Type& FunctionSkeletonImpl::get_type() const { + return m_type; +} + +} + +namespace std { + bool less::operator()( + const loki::pddl::FunctionSkeleton& left_function, + const loki::pddl::FunctionSkeleton& right_function) const { + return *left_function < *right_function; + } + + std::size_t hash::operator()(const loki::pddl::FunctionSkeletonImpl& function) const { + return function.hash_impl(); + } + +} diff --git a/src/domain/pddl/literal.cpp b/src/domain/pddl/literal.cpp new file mode 100644 index 00000000..db11bd1c --- /dev/null +++ b/src/domain/pddl/literal.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/domain/pddl/literal.hpp" + +#include "../../../include/loki/domain/pddl/atom.hpp" +#include "../../../include/loki/common/hash.hpp" +#include "../../../include/loki/common/collections.hpp" + + +namespace loki::pddl { +LiteralImpl::LiteralImpl(int identifier, bool is_negated, Atom atom) + : Base(identifier) + , m_is_negated(is_negated) + , m_atom(std::move(atom)) +{ +} + +bool LiteralImpl::is_structurally_equivalent_to_impl(const LiteralImpl& other) const { + return (m_is_negated == other.m_is_negated) && (m_atom == other.m_atom); +} + +size_t LiteralImpl::hash_impl() const { + return hash_combine(m_is_negated, m_atom); +} + +void LiteralImpl::str_impl(std::ostringstream& out, const FormattingOptions& /*options*/) const { + if (m_is_negated) { + out << "(not " << *m_atom << ")"; + } else { + out << *m_atom; + } +} + +bool LiteralImpl::is_negated() const { + return m_is_negated; +} + +const Atom& LiteralImpl::get_atom() const { + return m_atom; +} + +} + +namespace std { + bool less::operator()( + const loki::pddl::Literal& left_literal, + const loki::pddl::Literal& right_literal) const { + return *left_literal < *right_literal; + } + + std::size_t hash::operator()(const loki::pddl::LiteralImpl& literal) const { + return literal.hash_impl(); + } +} diff --git a/src/domain/pddl/object.cpp b/src/domain/pddl/object.cpp new file mode 100644 index 00000000..c23dd070 --- /dev/null +++ b/src/domain/pddl/object.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/domain/pddl/object.hpp" +#include "../../../include/loki/common/hash.hpp" +#include "../../../include/loki/common/collections.hpp" + + +namespace loki::pddl { +ObjectImpl::ObjectImpl(int identifier, std::string name, TypeList types) + : Base(identifier) + , m_name(std::move(name)) + , m_types(std::move(types)) +{ +} + +bool ObjectImpl::is_structurally_equivalent_to_impl(const ObjectImpl& other) const { + return (m_name == other.m_name) && (get_sorted_vector(m_types) == get_sorted_vector(other.m_types)); +} + +size_t ObjectImpl::hash_impl() const { + return hash_combine(m_name, hash_container(get_sorted_vector(m_types))); +} + +void ObjectImpl::str_impl(std::ostringstream& out, const FormattingOptions& /*options*/) const { + out << m_name; +} + +const std::string& ObjectImpl::get_name() const { + return m_name; +} + +const TypeList& ObjectImpl::get_bases() const { + return m_types; +} + +} + +namespace std { + bool less::operator()( + const loki::pddl::Object& left_object, + const loki::pddl::Object& right_object) const { + return *left_object < *right_object; + } + + std::size_t hash::operator()(const loki::pddl::ObjectImpl& object) const { + return object.hash_impl(); + } +} diff --git a/src/domain/pddl/parameter.cpp b/src/domain/pddl/parameter.cpp new file mode 100644 index 00000000..4a368720 --- /dev/null +++ b/src/domain/pddl/parameter.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/domain/pddl/parameter.hpp" + +#include "../../../include/loki/domain/pddl/type.hpp" +#include "../../../include/loki/domain/pddl/variable.hpp" +#include "../../../include/loki/common/hash.hpp" +#include "../../../include/loki/common/collections.hpp" + +#include + + +namespace loki::pddl { +ParameterImpl::ParameterImpl(int identifier, pddl::Variable variable, TypeList types) + : Base(identifier) + , m_variable(std::move(variable)) + , m_types(std::move(types)) +{ +} + +bool ParameterImpl::is_structurally_equivalent_to_impl(const ParameterImpl& other) const { + return (m_variable == other.m_variable) && (get_sorted_vector(m_types) == get_sorted_vector(other.m_types)); +} + +size_t ParameterImpl::hash_impl() const { + return hash_combine(m_variable, hash_container(get_sorted_vector(m_types))); +} + +void ParameterImpl::str_impl(std::ostringstream& out, const FormattingOptions& options) const { + str(out, options, true); +} + +void ParameterImpl::str(std::ostringstream& out, const FormattingOptions& /*options*/, bool typing_enabled) const { + out << *m_variable; + if (typing_enabled) { + assert(!m_types.empty()); + out << " - "; + if (m_types.size() > 1) { + out << "(either "; + for (size_t i = 0; i < m_types.size(); ++i) { + if (i != 0) out << " "; + out << *m_types[i]; + } + out << ")"; + } else if (m_types.size() == 1) { + out << *m_types.front(); + } + } +} + +const Variable& ParameterImpl::get_variable() const { + return m_variable; +} + +const TypeList& ParameterImpl::get_bases() const { + return m_types; +} + +} + +namespace std { + bool less::operator()( + const loki::pddl::Parameter& left_parameter, + const loki::pddl::Parameter& right_parameter) const { + return *left_parameter < *right_parameter; + } + + std::size_t hash::operator()(const loki::pddl::ParameterImpl& parameter) const { + return parameter.hash_impl(); + } +} diff --git a/src/domain/pddl/parser.cpp b/src/domain/pddl/parser.cpp new file mode 100644 index 00000000..6af6444b --- /dev/null +++ b/src/domain/pddl/parser.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "parser.hpp" +#include "unpacking_visitor.hpp" + +#include "../../../include/loki/domain/pddl/exceptions.hpp" +#include "../../../include/loki/domain/pddl/parser.hpp" +#include "../../../include/loki/domain/pddl/object.hpp" +#include "../../../include/loki/domain/pddl/parameter.hpp" +#include "../../../include/loki/domain/pddl/predicate.hpp" +#include "../../../include/loki/domain/pddl/type.hpp" +#include "../../../include/loki/domain/pddl/domain.hpp" +#include "../../../include/loki/domain/pddl/object.hpp" + +#include "parser/constants.hpp" +#include "parser/functions.hpp" +#include "parser/parameters.hpp" +#include "parser/predicates.hpp" +#include "parser/requirements.hpp" +#include "parser/types.hpp" +#include "parser/structure.hpp" +#include "parser/common.hpp" + +using namespace loki::domain; +using namespace std; + + +namespace loki { + +pddl::Domain parse(const ast::Domain& domain_node, Context& context) { + const auto domain_name = parse(domain_node.domain_name.name); + /* Requirements section */ + if (domain_node.requirements.has_value()) { + context.requirements = context.factories.requirements.get_or_create( + parse(domain_node.requirements.value(), context)); + context.positions.push_back(context.requirements, domain_node.requirements.value()); + } else { + // Default requirements + context.requirements = context.factories.requirements.get_or_create( + pddl::RequirementEnumSet{pddl::RequirementEnum::STRIPS}); + } + /* Types section */ + auto types = pddl::TypeList(); + if (domain_node.types.has_value()) { + if (!context.requirements->test(pddl::RequirementEnum::TYPING)) { + throw UndefinedRequirementError(pddl::RequirementEnum::TYPING, context.scopes.get_error_handler()(domain_node.types.value(), "")); + } + types = parse(domain_node.types.value(), context); + } + /* Constants section */ + auto constants = pddl::ObjectList(); + if (domain_node.constants.has_value()) { + constants = parse(domain_node.constants.value(), context); + } + /* Predicates section */ + auto predicates = pddl::PredicateList(); + if (domain_node.predicates.has_value()) { + predicates = parse(domain_node.predicates.value(), context); + } + /* Functions section */ + auto function_skeletons = pddl::FunctionSkeletonList(); + if (domain_node.functions.has_value()) { + function_skeletons = parse(domain_node.functions.value(), context); + } + /* Action Schema section */ + auto derived_predicate_list = pddl::DerivedPredicateList(); + auto action_list = pddl::ActionList(); + for (const auto& structure_node : domain_node.structures) { + auto variant = boost::apply_visitor(StructureVisitor(context), structure_node); + boost::apply_visitor(UnpackingVisitor(action_list, derived_predicate_list), variant); + } + // Check references + for (const auto& predicate : predicates) { + if (context.references.exists(predicate)) { + const auto& [_predicate, position, error_handler] = context.scopes.get(predicate->get_name()).value(); + throw UnusedPredicateError(predicate->get_name(), error_handler(position.value(), "")); + } + } + for (const auto& function_skeleton : function_skeletons) { + if (context.references.exists(function_skeleton)) { + const auto& [_function_skeleton, position, error_handler] = context.scopes.get(function_skeleton->get_name()).value(); + throw UnusedFunctionSkeletonError(function_skeleton->get_name(), error_handler(position.value(), "")); + } + } + + const auto domain = context.factories.domains.get_or_create(domain_name, context.requirements, types, constants, predicates, function_skeletons, action_list); + context.positions.push_back(domain, domain_node); + return domain; +} + +} diff --git a/src/domain/pddl/parser.hpp b/src/domain/pddl/parser.hpp new file mode 100644 index 00000000..ae4e341a --- /dev/null +++ b/src/domain/pddl/parser.hpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_DOMAIN_PDDL_PARSER_HPP_ +#define LOKI_SRC_DOMAIN_PDDL_PARSER_HPP_ + +#include "../../../include/loki/common/ast/config.hpp" +#include "../../../include/loki/domain/pddl/parser.hpp" + +#include + + +namespace loki { + +template +class SetInsertVisitor : boost::static_visitor { +private: + Context& context; + + SetInsertVisitor(Context& context_); + +public: +}; + +} + +#endif // LOKI_SRC_DOMAIN_PDDL_PARSER_HPP_ diff --git a/src/domain/pddl/parser/common.cpp b/src/domain/pddl/parser/common.cpp new file mode 100644 index 00000000..3f142d78 --- /dev/null +++ b/src/domain/pddl/parser/common.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "common.hpp" + +#include "../../../../include/loki/domain/pddl/exceptions.hpp" + +using namespace loki::domain; +using namespace std; + + +namespace loki { + +/* Name */ +string parse(const ast::Name& node) { + return node.characters; +} + +/* Variable */ +pddl::Variable parse(const ast::Variable& node, Context& context) { + const auto variable = context.factories.variables.get_or_create(node.characters); + // Declare variable as being referenced. + context.references.untrack(variable); + // Add position of PDDL object + context.positions.push_back(variable, node); + return variable; +} + +/* Term */ +TermDeclarationTermVisitor::TermDeclarationTermVisitor(Context& context_) + : context(context_) { } + + +pddl::Term TermDeclarationTermVisitor::operator()(const ast::Name& node) const { + const auto constant_name = parse(node); + // Test for undefined constant. + const auto binding = context.scopes.get(constant_name); + if (!binding.has_value()) { + throw UndefinedConstantError(constant_name, context.scopes.get_error_handler()(node, "")); + } + // Constant are not tracked and hence must not be untracked. + // Construct Term and return it + const auto& [constant, _position, _error_handler] = binding.value(); + const auto term = context.factories.terms.get_or_create(constant); + // Add position of PDDL object + context.positions.push_back(term, node); + return term; +} + + +pddl::Term TermDeclarationTermVisitor::operator()(const ast::Variable& node) const { + const auto variable = parse(node, context); + // Test for multiple definition + const auto binding = context.scopes.get(variable->get_name()); + if (binding.has_value()) { + const auto message_1 = context.scopes.get_error_handler()(node, "Defined here:"); + const auto& [_constant, position, error_handler] = binding.value(); + assert(position.has_value()); + const auto message_2 = error_handler(position.value(), "First defined here:"); + throw MultiDefinitionVariableError(variable->get_name(), message_1 + message_2); + } + // Add binding to scope + context.scopes.insert(variable->get_name(), variable, node); + // Construct Term and return it + const auto term = context.factories.terms.get_or_create(variable); + // Add position of PDDL object + context.positions.push_back(term, node); + return term; +} + + +TermReferenceTermVisitor::TermReferenceTermVisitor(Context& context_) + : context(context_) { } + +pddl::Term TermReferenceTermVisitor::operator()(const ast::Name& node) const { + const auto object_name = parse(node); + // Test for undefined constant. + const auto binding = context.scopes.get(object_name); + if (!binding.has_value()) { + throw UndefinedConstantError(object_name, context.scopes.get_error_handler()(node, "")); + } + // Construct Term and return it + const auto& [object, _position, _error_handler] = binding.value(); + context.references.untrack(object); + const auto term = context.factories.terms.get_or_create(object); + // Add position of PDDL object + context.positions.push_back(term, node); + return term; +} + +pddl::Term TermReferenceTermVisitor::operator()(const ast::Variable& node) const { + const auto variable = parse(node, context); + // Test for undefined variable + const auto binding = context.scopes.get(variable->get_name()); + if (!binding.has_value()) { + throw UndefinedVariableError(variable->get_name(), context.scopes.get_error_handler()(node, "")); + } + // Construct Term and return it + const auto term = context.factories.terms.get_or_create(variable); + // Add position of PDDL object + context.positions.push_back(term, node); + return term; +} + +/* Number */ +double parse(const ast::Number& node) { + return node.value; +} + +} diff --git a/src/domain/pddl/parser/common.hpp b/src/domain/pddl/parser/common.hpp new file mode 100644 index 00000000..692e8f25 --- /dev/null +++ b/src/domain/pddl/parser/common.hpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_DOMAIN_PDDL_PARSER_COMMON_HPP_ +#define LOKI_SRC_DOMAIN_PDDL_PARSER_COMMON_HPP_ + +#include "../../../../include/loki/domain/ast/ast.hpp" + +#include "../../../../include/loki/common/pddl/context.hpp" + + +namespace loki { + +/* Name */ +extern std::string parse(const domain::ast::Name& node); + +/* Variable */ +extern pddl::Variable parse(const domain::ast::Variable& node, Context& context); + +/* Term */ +struct TermDeclarationTermVisitor : boost::static_visitor { + Context& context; + + TermDeclarationTermVisitor(Context& context_); + + pddl::Term operator()(const domain::ast::Name& node) const; + pddl::Term operator()(const domain::ast::Variable& node) const; +}; + +struct TermReferenceTermVisitor : boost::static_visitor { + Context& context; + + TermReferenceTermVisitor(Context& context_); + + pddl::Term operator()(const domain::ast::Name& node) const; + pddl::Term operator()(const domain::ast::Variable& node) const; +}; + + +/* Number */ +extern double parse(const domain::ast::Number& node); + +} + +#endif // LOKI_SRC_DOMAIN_PDDL_PARSER_COMMON_HPP_ diff --git a/src/domain/pddl/parser/conditions.cpp b/src/domain/pddl/parser/conditions.cpp new file mode 100644 index 00000000..32b2a507 --- /dev/null +++ b/src/domain/pddl/parser/conditions.cpp @@ -0,0 +1,265 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "conditions.hpp" + +#include "literal.hpp" +#include "parameters.hpp" + +#include "../../../../include/loki/domain/pddl/exceptions.hpp" + + +namespace loki { +// parse a vector of goal descriptors +template +static pddl::ConditionList parse(const std::vector& nodes, Context& context) { + auto condition_list = pddl::ConditionList(); + for (const auto& node : nodes) { + condition_list.push_back(parse(node, context)); + } + return condition_list; +} + +pddl::Condition parse(const domain::ast::GoalDescriptor& node, Context& context) { + return boost::apply_visitor(ConditionVisitor(context), node); +} + +pddl::Condition parse(const domain::ast::GoalDescriptorAtom& node, Context& context) { + const auto condition = context.factories.conditions.get_or_create(parse(node.atom, context)); + context.positions.push_back(condition, node); + return condition; +} + +pddl::Condition parse(const domain::ast::GoalDescriptorLiteral& node, Context& context) { + // requires :negative-preconditions + if (!context.requirements->test(pddl::RequirementEnum::NEGATIVE_PRECONDITIONS)) { + throw UndefinedRequirementError(pddl::RequirementEnum::NEGATIVE_PRECONDITIONS, context.scopes.get_error_handler()(node, "")); + } + context.references.untrack(pddl::RequirementEnum::NEGATIVE_PRECONDITIONS); + const auto condition = context.factories.conditions.get_or_create(parse(node.literal, context)); + context.positions.push_back(condition, node); + return condition; +} + +pddl::Condition parse(const domain::ast::GoalDescriptorAnd& node, Context& context) { + auto condition_list = parse(node.goal_descriptors, context); + const auto condition = context.factories.conditions.get_or_create(condition_list); + context.positions.push_back(condition, node); + return condition; +} + +pddl::Condition parse(const domain::ast::GoalDescriptorOr& node, Context& context) { + // requires :disjunctive-preconditions + if (!context.requirements->test(pddl::RequirementEnum::DISJUNCTIVE_PRECONDITIONS)) { + throw UndefinedRequirementError(pddl::RequirementEnum::DISJUNCTIVE_PRECONDITIONS, context.scopes.get_error_handler()(node, "")); + } + context.references.untrack(pddl::RequirementEnum::DISJUNCTIVE_PRECONDITIONS); + auto condition_list = parse(node.goal_descriptors, context); + const auto condition = context.factories.conditions.get_or_create(condition_list); + context.positions.push_back(condition, node); + return condition; +} + +pddl::Condition parse(const domain::ast::GoalDescriptorNot& node, Context& context) { + // requires :disjunctive-preconditions + if (!context.requirements->test(pddl::RequirementEnum::NEGATIVE_PRECONDITIONS)) { + throw UndefinedRequirementError(pddl::RequirementEnum::NEGATIVE_PRECONDITIONS, context.scopes.get_error_handler()(node, "")); + } + context.references.untrack(pddl::RequirementEnum::NEGATIVE_PRECONDITIONS); + auto child_condition = parse(node.goal_descriptor, context); + const auto condition = context.factories.conditions.get_or_create(child_condition); + context.positions.push_back(condition, node); + return condition; +} + +pddl::Condition parse(const domain::ast::GoalDescriptorImply& node, Context& context) { + if (!context.requirements->test(pddl::RequirementEnum::DISJUNCTIVE_PRECONDITIONS)) { + throw UndefinedRequirementError(pddl::RequirementEnum::DISJUNCTIVE_PRECONDITIONS, context.scopes.get_error_handler()(node, "")); + } + context.references.untrack(pddl::RequirementEnum::DISJUNCTIVE_PRECONDITIONS); + auto condition_left = parse(node.goal_descriptor_left, context); + auto condition_right = parse(node.goal_descriptor_right, context); + const auto condition = context.factories.conditions.get_or_create(condition_left, condition_right); + context.positions.push_back(condition, node); + return condition; +} + +pddl::Condition parse(const domain::ast::GoalDescriptorExists& node, Context& context) { + if (!context.requirements->test(pddl::RequirementEnum::EXISTENTIAL_PRECONDITIONS)) { + throw UndefinedRequirementError(pddl::RequirementEnum::EXISTENTIAL_PRECONDITIONS, context.scopes.get_error_handler()(node, "")); + } + context.references.untrack(pddl::RequirementEnum::EXISTENTIAL_PRECONDITIONS); + context.scopes.open_scope(); + auto parameters = boost::apply_visitor(ParameterListVisitor(context), node.typed_list_of_variables); + for (const auto& parameter : parameters) { + context.references.track(parameter->get_variable()); + } + auto child_condition = parse(node.goal_descriptor, context); + // Check referenced_pointers + for (const auto& parameter : parameters) { + if (context.references.exists(parameter->get_variable())) { + const auto& [variable, position, error_handler] = context.scopes.get(parameter->get_variable()->get_name()).value(); + throw UnusedVariableError(variable->get_name(), error_handler(position.value(), "")); + } + } + + context.scopes.close_scope(); + auto condition = context.factories.conditions.get_or_create(parameters, child_condition); + context.positions.push_back(condition, node); + return condition; +} + +template +pddl::Condition parse_condition_forall(const domain::ast::TypedListOfVariables& parameters_node, const ConditionNode& condition_node, Context& context) { + context.scopes.open_scope(); + auto parameters = boost::apply_visitor(ParameterListVisitor(context), parameters_node); + for (const auto& parameter : parameters) { + context.references.track(parameter->get_variable()); + } + auto child_condition = parse(condition_node, context); + // Check referenced_pointers + for (const auto& parameter : parameters) { + if (context.references.exists(parameter->get_variable())) { + const auto& [variable, position, error_handler] = context.scopes.get(parameter->get_variable()->get_name()).value(); + throw UnusedVariableError(variable->get_name(), error_handler(position.value(), "")); + } + } + + context.scopes.close_scope(); + auto condition = context.factories.conditions.get_or_create(parameters, child_condition); + context.positions.push_back(condition, condition_node); + return condition; +} + +pddl::Condition parse(const domain::ast::GoalDescriptorForall& node, Context& context) { + if (!context.requirements->test(pddl::RequirementEnum::UNIVERSAL_PRECONDITIONS)) { + throw UndefinedRequirementError(pddl::RequirementEnum::UNIVERSAL_PRECONDITIONS, context.scopes.get_error_handler()(node, "")); + } + context.references.untrack(pddl::RequirementEnum::UNIVERSAL_PRECONDITIONS); + return parse_condition_forall(node.typed_list_of_variables, node.goal_descriptor, context); +} + +pddl::Condition parse(const domain::ast::GoalDescriptorFunctionComparison& node, Context& context) { + if (!context.requirements->test(pddl::RequirementEnum::NUMERIC_FLUENTS)) { + throw UndefinedRequirementError(pddl::RequirementEnum::NUMERIC_FLUENTS, context.scopes.get_error_handler()(node, "")); + } + throw NotImplementedError("parse(const domain::ast::GoalDescriptorFunctionComparison& node, Context& context)"); +} + + +pddl::Condition parse(const domain::ast::ConstraintGoalDescriptor& node, Context& context) { + return boost::apply_visitor(ConditionVisitor(context), node); +} + +pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorAnd& node, Context& context) { + auto condition_list = pddl::ConditionList(); + for (const auto& child_node : node.constraint_goal_descriptors) { + condition_list.push_back(parse(child_node, context)); + } + const auto condition = context.factories.conditions.get_or_create(condition_list); + context.positions.push_back(condition, node); + return condition; +} + +pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorForall& node, Context& context) { + if (!context.requirements->test(pddl::RequirementEnum::UNIVERSAL_PRECONDITIONS)) { + throw UndefinedRequirementError(pddl::RequirementEnum::UNIVERSAL_PRECONDITIONS, context.scopes.get_error_handler()(node, "")); + } + context.references.untrack(pddl::RequirementEnum::UNIVERSAL_PRECONDITIONS); + return parse_condition_forall(node.typed_list_of_variables, node.constraint_goal_descriptor, context); +} + +pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorAtEnd& /*node*/, Context& /*context*/) { + throw NotImplementedError("parse(const domain::ast::ConstraintGoalDescriptorAtEnd& node, Context& context)"); +} + +pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorAlways& /*node*/, Context& /*context*/) { + throw NotImplementedError("parse(const domain::ast::ConstraintGoalDescriptorAlways& node, Context& context)"); +} + +pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorSometime& /*node*/, Context& /*context*/) { + throw NotImplementedError("parse(const domain::ast::ConstraintGoalDescriptorSometime& node, Context& context)"); +} + +pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorWithin& /*node*/, Context& /*context*/) { + throw NotImplementedError("parse(const domain::ast::ConstraintGoalDescriptorWithin& node, Context& context)"); +} + +pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorAtMostOnce& /*node*/, Context& /*context*/) { + throw NotImplementedError("parse(const domain::ast::ConstraintGoalDescriptorAtMostOnce& node, Context& context)"); +} + +pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorSometimeAfter& /*node*/, Context& /*context*/) { + throw NotImplementedError("parse(const domain::ast::ConstraintGoalDescriptorSometimeAfter& node, Context& context)"); +} + +pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorSometimeBefore& /*node*/, Context& /*context*/) { + throw NotImplementedError("parse(const domain::ast::ConstraintGoalDescriptorSometimeBefore& node, Context& context)"); +} + +pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorAlwaysWithin& /*node*/, Context& /*context*/) { + throw NotImplementedError("parse(const domain::ast::ConstraintGoalDescriptorAlwaysWithin& node, Context& context)"); +} + +pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorHoldDuring& /*node*/, Context& /*context*/) { + throw NotImplementedError("parse(const domain::ast::ConstraintGoalDescriptorHoldDuring& node, Context& context)"); +} + +pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorHoldAfter& /*node*/, Context& /*context*/) { + throw NotImplementedError("parse(const domain::ast::ConstraintGoalDescriptorHoldAfter& node, Context& context)"); +} + + +pddl::Condition parse(const domain::ast::PreconditionGoalDescriptor& node, Context& context) { + return boost::apply_visitor(ConditionVisitor(context), node); +} + +pddl::Condition parse(const domain::ast::PreconditionGoalDescriptorSimple& node, Context& context) { + return parse(node.goal_descriptor, context); +} + +pddl::Condition parse(const domain::ast::PreconditionGoalDescriptorAnd& node, Context& context) { + auto condition_list = pddl::ConditionList(); + for (const auto& child_node : node.precondition_goal_descriptors) { + condition_list.push_back(parse(child_node, context)); + } + const auto condition = context.factories.conditions.get_or_create(condition_list); + context.positions.push_back(condition, node); + return condition; +} + +pddl::Condition parse(const domain::ast::PreconditionGoalDescriptorPreference& node, Context& context) { + if (!context.requirements->test(pddl::RequirementEnum::PREFERENCES)) { + throw UndefinedRequirementError(pddl::RequirementEnum::PREFERENCES, context.scopes.get_error_handler()(node, "")); + } + throw NotImplementedError("parse(const domain::ast::PreconditionGoalDescriptorPreference& node, Context& context)"); +} + +pddl::Condition parse(const domain::ast::PreconditionGoalDescriptorForall& node, Context& context) { + if (!context.requirements->test(pddl::RequirementEnum::UNIVERSAL_PRECONDITIONS)) { + throw UndefinedRequirementError(pddl::RequirementEnum::UNIVERSAL_PRECONDITIONS, context.scopes.get_error_handler()(node, "")); + } + context.references.untrack(pddl::RequirementEnum::UNIVERSAL_PRECONDITIONS); + return parse_condition_forall(node.typed_list_of_variables, node.precondition_goal_descriptor, context); +} + + + +ConditionVisitor::ConditionVisitor(Context& context_) + : context(context_) { } + +} diff --git a/src/domain/pddl/parser/conditions.hpp b/src/domain/pddl/parser/conditions.hpp new file mode 100644 index 00000000..a77be8d6 --- /dev/null +++ b/src/domain/pddl/parser/conditions.hpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_DOMAIN_PDDL_PARSER_CONDITIONS_HPP_ +#define LOKI_SRC_DOMAIN_PDDL_PARSER_CONDITIONS_HPP_ + +#include "../../../../include/loki/domain/ast/ast.hpp" +#include "../../../../include/loki/domain/pddl/parser.hpp" +#include "../../../../include/loki/domain/pddl/declarations.hpp" +#include "../../../../include/loki/domain/pddl/conditions.hpp" + +#include + + +namespace loki { + +extern pddl::Condition parse(const domain::ast::GoalDescriptor& node, Context& context); +extern pddl::Condition parse(const domain::ast::GoalDescriptorAtom& node, Context& context); +extern pddl::Condition parse(const domain::ast::GoalDescriptorLiteral& node, Context& context); +extern pddl::Condition parse(const domain::ast::GoalDescriptorAnd& node, Context& context); +extern pddl::Condition parse(const domain::ast::GoalDescriptorOr& node, Context& context); +extern pddl::Condition parse(const domain::ast::GoalDescriptorNot& node, Context& context); +extern pddl::Condition parse(const domain::ast::GoalDescriptorImply& node, Context& context); +extern pddl::Condition parse(const domain::ast::GoalDescriptorExists& node, Context& context); +extern pddl::Condition parse(const domain::ast::GoalDescriptorForall& node, Context& context); +extern pddl::Condition parse(const domain::ast::GoalDescriptorFunctionComparison& node, Context& context); + +extern pddl::Condition parse(const domain::ast::ConstraintGoalDescriptor& node, Context& context); +extern pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorAnd& node, Context& context); +extern pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorForall& node, Context& context); +extern pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorAtEnd& node, Context& context); +extern pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorAlways& node, Context& context); +extern pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorSometime& node, Context& context); +extern pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorWithin& node, Context& context); +extern pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorAtMostOnce& node, Context& context); +extern pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorSometimeAfter& node, Context& context); +extern pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorSometimeBefore& node, Context& context); +extern pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorAlwaysWithin& node, Context& context); +extern pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorHoldDuring& node, Context& context); +extern pddl::Condition parse(const domain::ast::ConstraintGoalDescriptorHoldAfter& node, Context& context); + +extern pddl::Condition parse(const domain::ast::PreconditionGoalDescriptor& node, Context& context); +extern pddl::Condition parse(const domain::ast::PreconditionGoalDescriptorSimple& node, Context& context); +extern pddl::Condition parse(const domain::ast::PreconditionGoalDescriptorAnd& node, Context& context); +extern pddl::Condition parse(const domain::ast::PreconditionGoalDescriptorPreference& node, Context& context); +extern pddl::Condition parse(const domain::ast::PreconditionGoalDescriptorForall& node, Context& context); + +struct ConditionVisitor : boost::static_visitor { + Context& context; + + ConditionVisitor(Context& context_); + + template + pddl::Condition operator()(const Node& node) const { + return parse(node, context); + } +}; + +} + +#endif // LOKI_SRC_DOMAIN_PDDL_PARSER_CONDITIONS_HPP_ diff --git a/src/domain/pddl/parser/constants.cpp b/src/domain/pddl/parser/constants.cpp new file mode 100644 index 00000000..74b6df37 --- /dev/null +++ b/src/domain/pddl/parser/constants.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "constants.hpp" + +#include "types.hpp" +#include "common.hpp" + +#include "../../../../include/loki/domain/pddl/exceptions.hpp" + +using namespace loki::domain; +using namespace std; + + +namespace loki { +static void test_multiple_definition(const pddl::Object& constant, const domain::ast::Name& node, const Context& context) { + const auto constant_name = constant->get_name(); + const auto binding = context.scopes.get(constant_name); + if (binding.has_value()) { + const auto message_1 = context.scopes.get_error_handler()(node, "Defined here:"); + auto message_2 = std::string(""); + const auto& [_object, position, error_handler] = binding.value(); + if (position.has_value()) { + message_2 = error_handler(position.value(), "First defined here:"); + } + throw MultiDefinitionConstantError(constant_name, message_1 + message_2); + } +} + + +static void insert_context_information(const pddl::Object& constant, const domain::ast::Name& node, Context& context) { + context.positions.push_back(constant, node); + context.scopes.insert(constant->get_name(), constant, node); +} + + +static pddl::Object parse_constant_definition(const domain::ast::Name& node, const pddl::TypeList& type_list, Context& context) { + const auto name = parse(node); + const auto constant = context.factories.objects.get_or_create(name, type_list); + test_multiple_definition(constant, node, context); + insert_context_information(constant, node, context); + return constant; +} + + +static pddl::ObjectList parse_constant_definitions(const std::vector nodes, const pddl::TypeList& type_list, Context& context) { + auto constant_list = pddl::ObjectList(); + for (const auto& node : nodes) { + constant_list.emplace_back(parse_constant_definition(node, type_list, context)); + } + return constant_list; +} + + +pddl::ObjectList parse(const ast::Constants& constants_node, Context& context) { + return boost::apply_visitor(ConstantListVisitor(context), constants_node.typed_list_of_names); +} + +ConstantListVisitor::ConstantListVisitor(Context& context_) + : context(context_) { } + +pddl::ObjectList ConstantListVisitor::operator()(const std::vector& name_nodes) { + // std::vector has single base type "object" + assert(context.scopes.get("object").has_value()); + const auto& [type, _position, _error_handler] = context.scopes.get("object").value(); + const auto constant_list = parse_constant_definitions(name_nodes, pddl::TypeList{type}, context); + return constant_list; +} + +pddl::ObjectList ConstantListVisitor::operator()(const ast::TypedListOfNamesRecursively& typed_list_of_names_recursively_node) { + if (!context.requirements->test(pddl::RequirementEnum::TYPING)) { + throw UndefinedRequirementError(pddl::RequirementEnum::TYPING, context.scopes.get_error_handler()(typed_list_of_names_recursively_node, "")); + } + context.references.untrack(pddl::RequirementEnum::TYPING); + const auto type_list = boost::apply_visitor(TypeReferenceTypeVisitor(context), + typed_list_of_names_recursively_node.type); + // TypedListOfNamesRecursively has user defined base types + auto constant_list = parse_constant_definitions(typed_list_of_names_recursively_node.names, type_list, context); + // Recursively add objects. + auto additional_objects = boost::apply_visitor(*this, typed_list_of_names_recursively_node.typed_list_of_names.get()); + constant_list.insert(constant_list.end(), additional_objects.begin(), additional_objects.end()); + return constant_list; +} + +} diff --git a/src/domain/pddl/parser/constants.hpp b/src/domain/pddl/parser/constants.hpp new file mode 100644 index 00000000..4503c729 --- /dev/null +++ b/src/domain/pddl/parser/constants.hpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_DOMAIN_PDDL_PARSER_CONSTANTS_HPP_ +#define LOKI_SRC_DOMAIN_PDDL_PARSER_CONSTANTS_HPP_ + +#include "../../../../include/loki/domain/ast/ast.hpp" +#include "../../../../include/loki/domain/pddl/declarations.hpp" +#include "../../../../include/loki/domain/pddl/parser.hpp" + + +namespace loki { + +/* Constants */ +extern pddl::ObjectList parse(const domain::ast::Constants& constants_node, Context& context); + +class ConstantListVisitor : boost::static_visitor { +private: + Context& context; + +public: + ConstantListVisitor(Context& context_); + + pddl::ObjectList operator()(const std::vector& name_nodes); + + pddl::ObjectList operator()(const domain::ast::TypedListOfNamesRecursively& typed_list_of_names_recursively_node); +}; + +} + +#endif // LOKI_SRC_DOMAIN_PDDL_PARSER_CONSTANTS_HPP_ diff --git a/src/domain/pddl/parser/effects.cpp b/src/domain/pddl/parser/effects.cpp new file mode 100644 index 00000000..5ab4a6bf --- /dev/null +++ b/src/domain/pddl/parser/effects.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "effects.hpp" + +#include "common.hpp" +#include "conditions.hpp" +#include "literal.hpp" +#include "parameters.hpp" +#include "functions.hpp" +#include "../../../../include/loki/domain/pddl/exceptions.hpp" + + +namespace loki { + +pddl::AssignOperatorEnum parse(const domain::ast::AssignOperatorAssign&) { + return pddl::AssignOperatorEnum::ASSIGN; +} + +pddl::AssignOperatorEnum parse(const domain::ast::AssignOperatorScaleUp&) { + return pddl::AssignOperatorEnum::SCALE_UP; +} + +pddl::AssignOperatorEnum parse(const domain::ast::AssignOperatorScaleDown&) { + return pddl::AssignOperatorEnum::SCALE_DOWN; +} + +pddl::AssignOperatorEnum parse(const domain::ast::AssignOperatorIncrease&) { + return pddl::AssignOperatorEnum::INCREASE; +} + +pddl::AssignOperatorEnum parse(const domain::ast::AssignOperatorDecrease&) { + return pddl::AssignOperatorEnum::DECREASE; +} + +pddl::AssignOperatorEnum parse(const domain::ast::AssignOperator& node) { + return boost::apply_visitor(AssignOperatorVisitor(), node); +} + + +pddl::Effect parse(const std::vector& effect_nodes, Context& context) { + auto effect_list = pddl::EffectList(); + for (const auto& effect_node : effect_nodes) { + effect_list.push_back(parse(effect_node, context)); + } + return context.factories.effects.get_or_create(effect_list); +} + +pddl::Effect parse(const domain::ast::Effect& node, Context& context) { + return boost::apply_visitor(EffectVisitor(context), node); +} + +pddl::Effect parse(const domain::ast::EffectProductionLiteral& node, Context& context) { + auto literal = parse(node.literal, context); + const auto effect = context.factories.effects.get_or_create(literal); + context.positions.push_back(effect, node); + return effect; +} + +pddl::Effect parse(const domain::ast::EffectProductionNumericFluentTotalCost& node, Context& context) { + if (!context.requirements->test(pddl::RequirementEnum::ACTION_COSTS)) { + throw UndefinedRequirementError(pddl::RequirementEnum::ACTION_COSTS, context.scopes.get_error_handler()(node, "")); + } + context.references.untrack(pddl::RequirementEnum::ACTION_COSTS); + const auto assign_operator_increase = parse(node.assign_operator_increase); + auto function_name = parse(node.function_symbol_total_cost.name); + assert(function_name == "total-cost"); + auto binding = context.scopes.get(function_name); + if (!binding.has_value()) { + throw UndefinedFunctionSkeletonError(function_name, context.scopes.get_error_handler()(node.function_symbol_total_cost, "")); + } + const auto& [function_skeleton, _position, _error_handler] = binding.value(); + const auto function = context.factories.functions.get_or_create(function_skeleton, pddl::TermList{}); + context.references.untrack(function->get_function_skeleton()); + const auto function_expression = boost::apply_visitor(FunctionExpressionVisitor(context), node.numeric_term); + const auto effect = context.factories.effects.get_or_create(assign_operator_increase, function, function_expression); + context.positions.push_back(effect, node); + return effect; +} + +pddl::Effect parse(const domain::ast::EffectProductionNumericFluentGeneral& node, Context& context) { + if (!context.requirements->test(pddl::RequirementEnum::NUMERIC_FLUENTS)) { + throw UndefinedRequirementError(pddl::RequirementEnum::NUMERIC_FLUENTS, context.scopes.get_error_handler()(node, "")); + } + context.references.untrack(pddl::RequirementEnum::NUMERIC_FLUENTS); + const auto assign_operator = parse(node.assign_operator); + const auto function = parse(node.function_head, context); + context.references.untrack(function->get_function_skeleton()); + const auto function_expression = parse(node.function_expression, context); + const auto effect = context.factories.effects.get_or_create(assign_operator, function, function_expression); + context.positions.push_back(effect, node); + return effect; +} + +pddl::Effect parse(const domain::ast::EffectProduction& node, Context& context) { + return boost::apply_visitor(EffectVisitor(context), node); +} + +pddl::Effect parse(const domain::ast::EffectConditionalForall& node, Context& context) { + context.scopes.open_scope(); + const auto parameters = boost::apply_visitor(ParameterListVisitor(context), node.typed_list_of_variables); + for (const auto& parameter : parameters) { + context.references.track(parameter->get_variable()); + } + const auto child_effect = parse(node.effect, context); + // Check referenced_pointers + for (const auto& parameter : parameters) { + if (context.references.exists(parameter->get_variable())) { + const auto& [variable, position, error_handler] = context.scopes.get(parameter->get_variable()->get_name()).value(); + throw UnusedVariableError(variable->get_name(), error_handler(position.value(), "")); + } + } + + context.scopes.close_scope(); + const auto effect = context.factories.effects.get_or_create(parameters, child_effect); + context.positions.push_back(effect, node); + return effect; +} + +pddl::Effect parse(const domain::ast::EffectConditionalWhen& node, Context& context) { + context.scopes.open_scope(); + const auto condition = parse(node.goal_descriptor, context); + const auto child_effect = parse(node.effect, context); + context.scopes.close_scope(); + const auto effect = context.factories.effects.get_or_create(condition, child_effect); + context.positions.push_back(effect, node); + return effect; +} + +pddl::Effect parse(const domain::ast::EffectConditional& node, Context& context) { + // requires :conditional-effects + if (!context.requirements->test(pddl::RequirementEnum::CONDITIONAL_EFFECTS)) { + throw UndefinedRequirementError(pddl::RequirementEnum::CONDITIONAL_EFFECTS, context.scopes.get_error_handler()(node, "")); + } + context.references.untrack(pddl::RequirementEnum::CONDITIONAL_EFFECTS); + const auto effect = boost::apply_visitor(EffectVisitor(context), node); + context.positions.push_back(effect, node); + return effect; +} + +EffectVisitor::EffectVisitor(Context& context_) + : context(context_) { } + +} \ No newline at end of file diff --git a/src/domain/pddl/parser/effects.hpp b/src/domain/pddl/parser/effects.hpp new file mode 100644 index 00000000..b3fb5c94 --- /dev/null +++ b/src/domain/pddl/parser/effects.hpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_DOMAIN_PDDL_PARSER_EFFECTS_HPP_ +#define LOKI_SRC_DOMAIN_PDDL_PARSER_EFFECTS_HPP_ + +#include "../../../../include/loki/domain/ast/ast.hpp" +#include "../../../../include/loki/domain/pddl/parser.hpp" +#include "../../../../include/loki/domain/pddl/declarations.hpp" +#include "../../../../include/loki/domain/pddl/effects.hpp" + +#include + + +namespace loki { + +/* AssignOperator */ +extern pddl::AssignOperatorEnum parse(const domain::ast::AssignOperatorAssign& node); +extern pddl::AssignOperatorEnum parse(const domain::ast::AssignOperatorScaleUp& node); +extern pddl::AssignOperatorEnum parse(const domain::ast::AssignOperatorScaleDown& node); +extern pddl::AssignOperatorEnum parse(const domain::ast::AssignOperatorIncrease& node); +extern pddl::AssignOperatorEnum parse(const domain::ast::AssignOperatorDecrease& node); +extern pddl::AssignOperatorEnum parse(const domain::ast::AssignOperator& node); + +struct AssignOperatorVisitor : boost::static_visitor { + template + pddl::AssignOperatorEnum operator()(const Node& node) const { + return parse(node); + } +}; + + +/* Effects */ +extern pddl::Effect parse(const std::vector& effect_nodes, Context& context); +extern pddl::Effect parse(const domain::ast::Effect& node, Context& context); +extern pddl::Effect parse(const domain::ast::EffectProductionLiteral& node, Context& context); +extern pddl::Effect parse(const domain::ast::EffectProductionNumericFluentTotalCost& node, Context& context); +extern pddl::Effect parse(const domain::ast::EffectProductionNumericFluentGeneral& node, Context& context); +extern pddl::Effect parse(const domain::ast::EffectProduction& node, Context& context); +extern pddl::Effect parse(const domain::ast::EffectConditionalForall& node, Context& context); +extern pddl::Effect parse(const domain::ast::EffectConditionalWhen& node, Context& context); +extern pddl::Effect parse(const domain::ast::EffectConditional& node, Context& context); + +struct EffectVisitor : boost::static_visitor { + Context& context; + + EffectVisitor(Context& context_); + + template + pddl::Effect operator()(const Node& node) const { + return parse(node, context); + } + +}; + +} + +#endif // LOKI_SRC_DOMAIN_PDDL_PARSER_EFFECTS_HPP_ diff --git a/src/domain/pddl/parser/functions.cpp b/src/domain/pddl/parser/functions.cpp new file mode 100644 index 00000000..db700439 --- /dev/null +++ b/src/domain/pddl/parser/functions.cpp @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "functions.hpp" + +#include "parameters.hpp" +#include "common.hpp" + +#include "../../../../include/loki/domain/pddl/exceptions.hpp" + + +namespace loki { + +/* MultiOperator */ +pddl::MultiOperatorEnum MultiOperatorVisitor::operator()(const domain::ast::MultiOperatorMul&) const { + return pddl::MultiOperatorEnum::MUL; +} + +pddl::MultiOperatorEnum MultiOperatorVisitor::operator()(const domain::ast::MultiOperatorPlus&) const { + return pddl::MultiOperatorEnum::PLUS; +} + + +/* BinaryOperator */ +pddl::BinaryOperatorEnum MultiToBinaryOperatorVisitor::operator()(const domain::ast::MultiOperatorMul&) const { + return pddl::BinaryOperatorEnum::MUL; +} + +pddl::BinaryOperatorEnum MultiToBinaryOperatorVisitor::operator()(const domain::ast::MultiOperatorPlus&) const { + return pddl::BinaryOperatorEnum::PLUS; +} + + +pddl::BinaryOperatorEnum BinaryOperatorVisitor::operator()(const domain::ast::BinaryOperatorDiv&) const { + return pddl::BinaryOperatorEnum::DIV; +} + +pddl::BinaryOperatorEnum BinaryOperatorVisitor::operator()(const domain::ast::BinaryOperatorMinus&) const { + return pddl::BinaryOperatorEnum::MINUS; +} + +pddl::BinaryOperatorEnum BinaryOperatorVisitor::operator()(const domain::ast::MultiOperator& node) const { + return boost::apply_visitor(MultiToBinaryOperatorVisitor(), node); +} + + +/* FunctionExpression */ +pddl::FunctionExpression parse(const domain::ast::FunctionExpression& node, Context& context) { + return boost::apply_visitor(FunctionExpressionVisitor(context), node); +} + +pddl::FunctionExpression parse(const domain::ast::FunctionExpressionNumber& node, Context& context) { + const auto number = parse(node.number); + const auto function_expression = context.factories.function_expressions.get_or_create(number); + context.positions.push_back(function_expression, node); + return function_expression; +} + +pddl::FunctionExpression parse(const domain::ast::FunctionExpressionBinaryOp& node, Context& context) { + const auto binary_operator = boost::apply_visitor(BinaryOperatorVisitor(), node.binary_operator); + const auto left_function_expression = parse(node.function_expression_left, context); + const auto right_function_expression = parse(node.function_expression_right, context); + const auto function_expression = context.factories.function_expressions.get_or_create(binary_operator, left_function_expression, right_function_expression); + context.positions.push_back(function_expression, node); + return function_expression; +} + +pddl::FunctionExpression parse(const domain::ast::FunctionExpressionMinus& node, Context& context) { + const auto child_function_expression = parse(node.function_expression, context); + const auto function_expression = context.factories.function_expressions.get_or_create(child_function_expression); + context.positions.push_back(function_expression, node); + return function_expression; +} + +pddl::FunctionExpression parse(const domain::ast::FunctionExpressionHead node, Context& context) { + const auto function = parse(node.function_head, context); + const auto function_expression = context.factories.function_expressions.get_or_create(function); + context.positions.push_back(function_expression, node); + return function_expression; +} + +FunctionExpressionVisitor::FunctionExpressionVisitor(Context& context_) + : context(context_) { } + + +/* Function */ +pddl::Function parse(const domain::ast::FunctionHead& node, Context& context) { + const auto function_skeleton = parse_function_skeleton_reference(node.function_symbol, context); + auto term_list = pddl::TermList(); + for (const auto& term_node : node.terms) { + term_list.push_back(boost::apply_visitor(TermReferenceTermVisitor(context), term_node)); + } + if (function_skeleton->get_parameters().size() != term_list.size()) { + throw MismatchedFunctionSkeletonTermListError(function_skeleton, term_list, context.scopes.get_error_handler()(node, "")); + } + const auto function = context.factories.functions.get_or_create(function_skeleton, term_list); + context.positions.push_back(function, node); + context.references.untrack(function->get_function_skeleton()); + return function; +} + + +/* FunctionSkeleton */ +pddl::FunctionSkeleton parse_function_skeleton_reference(const domain::ast::FunctionSymbol& node, Context& context) { + auto function_name = parse(node.name); + auto binding = context.scopes.get(function_name); + if (!binding.has_value()) { + throw UndefinedFunctionSkeletonError(function_name, context.scopes.get_error_handler()(node, "")); + } + const auto& [function_skeleton, _position, _error_handler] = binding.value(); + context.references.untrack(function_skeleton); + return function_skeleton; +} + + +static void test_multiple_definition(const pddl::FunctionSkeleton& function_skeleton, const domain::ast::Name& node, const Context& context) { + const auto function_name = function_skeleton->get_name(); + const auto binding = context.scopes.get(function_name); + if (binding.has_value()) { + const auto message_1 = context.scopes.get_error_handler()(node, "Defined here:"); + auto message_2 = std::string(""); + const auto& [_function_skeleton, position, error_handler] = binding.value(); + if (position.has_value()) { + message_2 = error_handler(position.value(), "First defined here:"); + } + throw MultiDefinitionFunctionSkeletonError(function_name, message_1 + message_2); + } +} + + +static void insert_context_information(const pddl::FunctionSkeleton& function_skeleton, const domain::ast::Name& node, Context& context) { + context.positions.push_back(function_skeleton, node); + context.scopes.insert(function_skeleton->get_name(), function_skeleton, node); + context.references.track(function_skeleton); +} + + +pddl::FunctionSkeleton parse(const domain::ast::AtomicFunctionSkeletonTotalCost& node, Context& context) { + if (!context.requirements->test(pddl::RequirementEnum::ACTION_COSTS)) { + throw UndefinedRequirementError(pddl::RequirementEnum::ACTION_COSTS, context.positions.get_error_handler()(node, "")); + } else { + context.references.untrack(pddl::RequirementEnum::ACTION_COSTS); + } + if ((!context.requirements->test(pddl::RequirementEnum::ACTION_COSTS)) + && (!context.requirements->test(pddl::RequirementEnum::NUMERIC_FLUENTS))) { + throw UndefinedRequirementError(pddl::RequirementEnum::NUMERIC_FLUENTS, context.positions.get_error_handler()(node, "")); + } else { + context.references.untrack(pddl::RequirementEnum::ACTION_COSTS); + context.references.untrack(pddl::RequirementEnum::NUMERIC_FLUENTS); + } + + assert(context.scopes.get("number").has_value()); + const auto& [type, _position, _error_handler] = context.scopes.get("number").value(); + auto function_name = parse(node.function_symbol.name); + auto function_skeleton = context.factories.function_skeletons.get_or_create(function_name, pddl::ParameterList{}, type); + + test_multiple_definition(function_skeleton, node.function_symbol.name, context); + insert_context_information(function_skeleton, node.function_symbol.name, context); + + return function_skeleton; +} + +pddl::FunctionSkeleton parse(const domain::ast::AtomicFunctionSkeletonGeneral& node, Context& context) { + if (!context.requirements->test(pddl::RequirementEnum::NUMERIC_FLUENTS)) { + throw UndefinedRequirementError(pddl::RequirementEnum::NUMERIC_FLUENTS, context.positions.get_error_handler()(node, "")); + } + context.references.untrack(pddl::RequirementEnum::NUMERIC_FLUENTS); + + context.scopes.open_scope(); + auto function_parameters = boost::apply_visitor(ParameterListVisitor(context), node.arguments); + context.scopes.close_scope(); + + assert(context.scopes.get("number").has_value()); + const auto& [type, _position, _error_handler] = context.scopes.get("number").value(); + auto function_name = parse(node.function_symbol.name); + auto function_skeleton = context.factories.function_skeletons.get_or_create(function_name, function_parameters, type); + + test_multiple_definition(function_skeleton, node.function_symbol.name, context); + insert_context_information(function_skeleton, node.function_symbol.name, context); + + return function_skeleton; +} + +AtomicFunctionSkeletonVisitor::AtomicFunctionSkeletonVisitor(Context& context_) + : context(context_) { } + + +/* FunctionSkeletonList */ +static pddl::FunctionSkeletonList parse_function_skeleton_definitions(const std::vector& nodes, Context& context) { + auto function_skeleton_list = pddl::FunctionSkeletonList(); + for (const auto& node : nodes) { + auto function_skeleton = boost::apply_visitor(AtomicFunctionSkeletonVisitor(context), node); + function_skeleton_list.push_back(function_skeleton); + } + return function_skeleton_list; +} + +pddl::FunctionSkeletonList parse(const std::vector& formula_skeleton_nodes, Context& context) { + auto function_skeleton_list = parse_function_skeleton_definitions(formula_skeleton_nodes, context); + return function_skeleton_list; +} + +pddl::FunctionSkeletonList parse(const domain::ast::FunctionTypedListOfAtomicFunctionSkeletonsRecursively& function_skeleton_list_recursively_node, Context& context) { + auto function_skeleton_list = parse_function_skeleton_definitions(function_skeleton_list_recursively_node.atomic_function_skeletons, context); + + if (function_skeleton_list_recursively_node.function_typed_list_of_atomic_function_skeletons.has_value()) { + auto add_function_skeleton_list = boost::apply_visitor(FunctionSkeletonListVisitor(context), function_skeleton_list_recursively_node.function_typed_list_of_atomic_function_skeletons.value().get()); + function_skeleton_list.insert(function_skeleton_list.end(), add_function_skeleton_list.begin(), add_function_skeleton_list.end()); + } + return function_skeleton_list; +} + +pddl::FunctionSkeletonList parse(const domain::ast::Functions& functions_node, Context& context) { + return boost::apply_visitor(FunctionSkeletonListVisitor(context), functions_node.function_types_list_of_atomic_function_skeletons); +} + +FunctionSkeletonListVisitor::FunctionSkeletonListVisitor(Context& context_) + : context(context_) { } + +} \ No newline at end of file diff --git a/src/domain/pddl/parser/functions.hpp b/src/domain/pddl/parser/functions.hpp new file mode 100644 index 00000000..fbbba835 --- /dev/null +++ b/src/domain/pddl/parser/functions.hpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_DOMAIN_PDDL_PARSER_FUNCTIONS_HPP_ +#define LOKI_SRC_DOMAIN_PDDL_PARSER_FUNCTIONS_HPP_ + +#include "../../../../include/loki/domain/ast/ast.hpp" +#include "../../../../include/loki/domain/pddl/parser.hpp" +#include "../../../../include/loki/domain/pddl/declarations.hpp" +#include "../../../../include/loki/domain/pddl/function_skeleton.hpp" +#include "../../../../include/loki/domain/pddl/function_expressions.hpp" + +#include + + +namespace loki { +/* MultiOperator */ +struct MultiOperatorVisitor : boost::static_visitor { + pddl::MultiOperatorEnum operator()(const domain::ast::MultiOperatorMul& node) const; + pddl::MultiOperatorEnum operator()(const domain::ast::MultiOperatorPlus& node) const; +}; + + +/* BinaryOperator */ +struct MultiToBinaryOperatorVisitor : boost::static_visitor { + pddl::BinaryOperatorEnum operator()(const domain::ast::MultiOperatorMul& node) const; + pddl::BinaryOperatorEnum operator()(const domain::ast::MultiOperatorPlus& node) const; +}; + +struct BinaryOperatorVisitor : boost::static_visitor { + pddl::BinaryOperatorEnum operator()(const domain::ast::BinaryOperatorDiv& node) const; + pddl::BinaryOperatorEnum operator()(const domain::ast::BinaryOperatorMinus& node) const; + pddl::BinaryOperatorEnum operator()(const domain::ast::MultiOperator& node) const; +}; + + +/* FunctionExpression */ +extern pddl::FunctionExpression parse(const domain::ast::FunctionExpressionNumber& node, Context& context); +extern pddl::FunctionExpression parse(const domain::ast::FunctionExpressionBinaryOp& node, Context& context); +extern pddl::FunctionExpression parse(const domain::ast::FunctionExpressionMinus& node, Context& context); +extern pddl::FunctionExpression parse(const domain::ast::FunctionExpressionHead node, Context& context); +extern pddl::FunctionExpression parse(const domain::ast::FunctionExpression& node, Context& context); + +class FunctionExpressionVisitor : boost::static_visitor { +private: + Context& context; + +public: + FunctionExpressionVisitor(Context& context_); + + template + pddl::FunctionExpression operator()(const Node& node) const { + return parse(node, context); + } +}; + + +/* Function */ +extern pddl::Function parse(const domain::ast::FunctionHead& node, Context& context); + + +/* FunctionSkeleton */ +extern pddl::FunctionSkeleton parse_function_skeleton_reference(const domain::ast::FunctionSymbol& node, Context& context); +extern pddl::FunctionSkeleton parse(const domain::ast::AtomicFunctionSkeletonTotalCost& node); +extern pddl::FunctionSkeleton parse(const domain::ast::AtomicFunctionSkeletonGeneral& node); + + +class AtomicFunctionSkeletonVisitor : boost::static_visitor { +private: + Context& context; + +public: + AtomicFunctionSkeletonVisitor(Context& context_); + + template + pddl::FunctionSkeleton operator()(const Node& node) { + return parse(node, context); + } +}; + + +/* FunctionSkeletonList */ +extern pddl::FunctionSkeletonList parse(const std::vector& formula_skeleton_nodes); +extern pddl::FunctionSkeletonList parse(const domain::ast::FunctionTypedListOfAtomicFunctionSkeletonsRecursively& function_skeleton_list_recursively_node); +extern pddl::FunctionSkeletonList parse(const domain::ast::Functions& functions_node, Context& context); + +class FunctionSkeletonListVisitor : boost::static_visitor { +private: + Context& context; + +public: + FunctionSkeletonListVisitor(Context& context_); + + template + pddl::FunctionSkeletonList operator()(const Node& node) { + return parse(node, context); + } +}; + +} + +#endif // LOKI_SRC_DOMAIN_PDDL_PARSER_FUNCTIONS_HPP_ diff --git a/src/domain/pddl/parser/literal.cpp b/src/domain/pddl/parser/literal.cpp new file mode 100644 index 00000000..3ea1af5c --- /dev/null +++ b/src/domain/pddl/parser/literal.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "literal.hpp" +#include "common.hpp" + +#include "../../../../include/loki/domain/pddl/exceptions.hpp" + + +namespace loki { + +pddl::Atom parse(const domain::ast::AtomicFormulaOfTermsPredicate& atomic_formula_of_terms_node, Context& context) { + auto predicate_name = parse(atomic_formula_of_terms_node.predicate.name); + auto binding = context.scopes.get(predicate_name); + if (!binding.has_value()) { + throw UndefinedPredicateError(predicate_name, context.scopes.get_error_handler()(atomic_formula_of_terms_node.predicate, "")); + } + auto term_list = pddl::TermList(); + for (const auto& term_node : atomic_formula_of_terms_node.terms) { + term_list.push_back(boost::apply_visitor(TermReferenceTermVisitor(context), term_node)); + } + const auto& [predicate, _position, _error_handler] = binding.value(); + if (predicate->get_parameters().size() != term_list.size()) { + throw MismatchedPredicateTermListError(predicate, term_list, context.scopes.get_error_handler()(atomic_formula_of_terms_node, "")); + } + context.references.untrack(predicate); + const auto atom = context.factories.atoms.get_or_create(predicate, term_list); + context.positions.push_back(atom, atomic_formula_of_terms_node); + return atom; +} + +pddl::Atom parse(const domain::ast::AtomicFormulaOfTermsEquality& atomic_formula_of_terms_node, Context& context) { + // requires :equality + if (!context.requirements->test(pddl::RequirementEnum::EQUALITY)) { + throw UndefinedRequirementError(pddl::RequirementEnum::EQUALITY, context.scopes.get_error_handler()(atomic_formula_of_terms_node, "")); + } + context.references.untrack(pddl::RequirementEnum::EQUALITY); + assert(context.scopes.get("=").has_value()); + const auto& [equal_predicate, _position, _error_handler] = context.scopes.get("=").value(); + auto left_term = boost::apply_visitor(TermReferenceTermVisitor(context), atomic_formula_of_terms_node.term_left); + auto right_term = boost::apply_visitor(TermReferenceTermVisitor(context), atomic_formula_of_terms_node.term_right); + const auto atom = context.factories.atoms.get_or_create( + equal_predicate, + pddl::TermList{left_term, right_term}); + context.positions.push_back(atom, atomic_formula_of_terms_node); + return atom; +} + +pddl::Atom parse(const domain::ast::AtomicFormulaOfTerms& atomic_formula_of_terms_node, Context& context) { + return boost::apply_visitor(AtomicFormulaOfTermsVisitor(context), atomic_formula_of_terms_node); +} + + +AtomicFormulaOfTermsVisitor::AtomicFormulaOfTermsVisitor(Context& context_) + : context(context_) { } + + +pddl::Literal parse(const domain::ast::Atom& atom_node, Context& context) { + const auto literal = context.factories.literals.get_or_create(false, parse(atom_node.atomic_formula_of_terms, context)); + context.positions.push_back(literal, atom_node); + return literal; +} + +pddl::Literal parse(const domain::ast::NegatedAtom& negated_atom_node, Context& context) { + const auto literal = context.factories.literals.get_or_create(true, parse(negated_atom_node.atomic_formula_of_terms, context)); + context.positions.push_back(literal, negated_atom_node); + return literal; +} + +pddl::Literal parse(const domain::ast::Literal& literal_node, Context& context) { + return boost::apply_visitor(LiteralVisitor(context), literal_node); +} + + +LiteralVisitor::LiteralVisitor(Context& context_) + : context(context_) { } + +} \ No newline at end of file diff --git a/src/domain/pddl/parser/literal.hpp b/src/domain/pddl/parser/literal.hpp new file mode 100644 index 00000000..d88654b3 --- /dev/null +++ b/src/domain/pddl/parser/literal.hpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_DOMAIN_PDDL_PARSER_LITERAL_HPP_ +#define LOKI_SRC_DOMAIN_PDDL_PARSER_LITERAL_HPP_ + +#include "../../../../include/loki/domain/ast/ast.hpp" +#include "../../../../include/loki/domain/pddl/parser.hpp" + + +namespace loki { + +/* Atom */ +extern pddl::Atom parse(const domain::ast::AtomicFormulaOfTermsPredicate& atomic_formula_of_terms_node, Context& context); +extern pddl::Atom parse(const domain::ast::AtomicFormulaOfTermsEquality& atomic_formula_of_terms_node, Context& context); +extern pddl::Atom parse(const domain::ast::AtomicFormulaOfTerms& atomic_formula_of_terms_node, Context& context); + +struct AtomicFormulaOfTermsVisitor : boost::static_visitor { + Context& context; + + AtomicFormulaOfTermsVisitor(Context& context_); + + template + pddl::Atom operator()(const Node& node) const { + return parse(node, context); + } +}; + + +/* Literal */ +extern pddl::Literal parse(const domain::ast::Atom& atom_node, Context& context); +extern pddl::Literal parse(const domain::ast::NegatedAtom& negated_atom_node, Context& context); +extern pddl::Literal parse(const domain::ast::Literal& literal_node, Context& context); + +struct LiteralVisitor : boost::static_visitor { + Context& context; + + LiteralVisitor(Context& context_); + + template + pddl::Literal operator()(const Node& node) const { + return parse(node, context); + } +}; + +} + +#endif // LOKI_SRC_DOMAIN_PDDL_PARSER_OBJECTS_HPP_ diff --git a/src/domain/pddl/parser/parameters.cpp b/src/domain/pddl/parser/parameters.cpp new file mode 100644 index 00000000..af0fbaee --- /dev/null +++ b/src/domain/pddl/parser/parameters.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "parameters.hpp" + +#include "types.hpp" +#include "common.hpp" + +#include "../../../../include/loki/domain/pddl/exceptions.hpp" + +using namespace loki::domain; +using namespace std; + + +namespace loki { + +static void test_multiple_definition(const pddl::Variable& variable, const ast::Variable& node, const Context& context) { + const auto binding = context.scopes.get(variable->get_name()); + if (binding.has_value()) { + const auto message_1 = context.scopes.get_error_handler()(node, "Defined here:"); + auto message_2 = std::string(""); + const auto& [_variable, position, error_handler] = binding.value(); + if (position.has_value()) { + message_2 = error_handler(position.value(), "First defined here:"); + } + throw MultiDefinitionVariableError(variable->get_name(), message_1 + message_2); + } +} + + +static void insert_context_information(const pddl::Variable& variable, const ast::Variable& node, Context& context) { + context.scopes.insert(variable->get_name(), variable, node); +} + + +static pddl::Parameter parse_parameter_definition(const domain::ast::Variable& variable_node, const pddl::TypeList& type_list, Context& context) { + const auto variable = parse(variable_node, context); + test_multiple_definition(variable, variable_node, context); + insert_context_information(variable, variable_node, context); + + const auto parameter = context.factories.parameters.get_or_create(variable, type_list); + context.positions.push_back(parameter, variable_node); + return parameter; +} + + +static pddl::ParameterList parse_parameter_definitions(const std::vector& variable_nodes, const pddl::TypeList& type_list, Context& context) { + auto parameter_list = pddl::ParameterList(); + for (const auto& variable_node : variable_nodes) { + parameter_list.emplace_back(parse_parameter_definition(variable_node, type_list, context)); + } + return parameter_list; +} + + +ParameterListVisitor::ParameterListVisitor(Context& context_) + : context(context_) { } + +pddl::ParameterList ParameterListVisitor::operator()(const std::vector& nodes) { + // std::vector has single base type "object" + const auto type = context.factories.types.get_or_create("object"); + auto parameter_list = parse_parameter_definitions(nodes, pddl::TypeList{type}, context); + return parameter_list; +} + +pddl::ParameterList ParameterListVisitor::operator()(const ast::TypedListOfVariablesRecursively& node) { + // requires :typing + if (!context.requirements->test(pddl::RequirementEnum::TYPING)) { + throw UndefinedRequirementError(pddl::RequirementEnum::TYPING, context.scopes.get_error_handler()(node, "")); + } + context.references.untrack(pddl::RequirementEnum::TYPING); + const auto type_list = boost::apply_visitor(TypeReferenceTypeVisitor(context), node.type); + // TypedListOfVariablesRecursively has user defined types + auto parameter_list = parse_parameter_definitions(node.variables, type_list, context); + // Recursively add parameters. + auto additional_parameters = boost::apply_visitor(*this, node.typed_list_of_variables.get()); + parameter_list.insert(parameter_list.end(), additional_parameters.begin(), additional_parameters.end()); + return parameter_list; +} + + +} diff --git a/src/domain/pddl/parser/parameters.hpp b/src/domain/pddl/parser/parameters.hpp new file mode 100644 index 00000000..803bac17 --- /dev/null +++ b/src/domain/pddl/parser/parameters.hpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_DOMAIN_PDDL_PARSER_PARAMETERS_HPP_ +#define LOKI_SRC_DOMAIN_PDDL_PARSER_PARAMETERS_HPP_ + +#include "../../../../include/loki/common/ast/config.hpp" +#include "../../../../include/loki/domain/ast/ast.hpp" +#include "../../../../include/loki/domain/pddl/parameter.hpp" +#include "../../../../include/loki/domain/pddl/parser.hpp" + + +namespace loki { + +/* ParameterList */ +class ParameterListVisitor : boost::static_visitor { +private: + Context& context; + +public: + ParameterListVisitor(Context& context_); + + pddl::ParameterList operator()(const std::vector& nodes); + + pddl::ParameterList operator()(const domain::ast::TypedListOfVariablesRecursively& node); +}; + + +} + +#endif // LOKI_SRC_DOMAIN_PDDL_PARSER_PARAMETERS_HPP_ diff --git a/src/domain/pddl/parser/predicates.cpp b/src/domain/pddl/parser/predicates.cpp new file mode 100644 index 00000000..e353b1d4 --- /dev/null +++ b/src/domain/pddl/parser/predicates.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "predicates.hpp" +#include "parameters.hpp" +#include "common.hpp" + +#include "../../../../include/loki/domain/pddl/exceptions.hpp" + + +namespace loki { + +static void test_multiple_definition(const pddl::Predicate& predicate, const domain::ast::Predicate& node, const Context& context) { + const auto predicate_name = predicate->get_name(); + const auto binding = context.scopes.get(predicate_name); + if (binding.has_value()) { + const auto message_1 = context.scopes.get_error_handler()(node, "Defined here:"); + auto message_2 = std::string(""); + const auto& [_predicate, position, error_handler] = binding.value(); + if (position.has_value()) { + message_2 = error_handler(position.value(), "First defined here:"); + } + throw MultiDefinitionPredicateError(predicate_name, message_1 + message_2); + } +} + + +static void insert_context_information(const pddl::Predicate& predicate, const domain::ast::Predicate& node, Context& context) { + context.positions.push_back(predicate, node); + context.scopes.insert(predicate->get_name(), predicate, node); + context.references.track(predicate); +} + + +static pddl::Predicate parse_predicate_definition(const domain::ast::AtomicFormulaSkeleton& node, Context& context) { + context.scopes.open_scope(); + const auto parameters = boost::apply_visitor(ParameterListVisitor(context),node.typed_list_of_variables); + context.scopes.close_scope(); + const auto predicate_name = parse(node.predicate.name); + const auto predicate = context.factories.predicates.get_or_create(predicate_name, parameters); + test_multiple_definition(predicate, node.predicate, context); + insert_context_information(predicate, node.predicate, context); + return predicate; +} + + +static pddl::PredicateList parse_predicate_definitions(const std::vector& nodes, Context& context) { + auto predicate_list = pddl::PredicateList(); + for (const auto& node : nodes) { + predicate_list.emplace_back(parse_predicate_definition(node, context)); + } + return predicate_list; +} + + +pddl::PredicateList parse(const domain::ast::Predicates& predicates_node, Context& context) { + const auto predicate_list = parse_predicate_definitions(predicates_node.atomic_formula_skeletons, context); + return predicate_list; +} + +} diff --git a/src/domain/pddl/parser/predicates.hpp b/src/domain/pddl/parser/predicates.hpp new file mode 100644 index 00000000..f527289a --- /dev/null +++ b/src/domain/pddl/parser/predicates.hpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_DOMAIN_PDDL_PARSER_PREDICATES_HPP_ +#define LOKI_SRC_DOMAIN_PDDL_PARSER_PREDICATES_HPP_ + +#include "../../../../include/loki/domain/ast/ast.hpp" +#include "../../../../include/loki/domain/pddl/parser.hpp" +#include "../../../../include/loki/domain/pddl/predicate.hpp" + + +namespace loki { + +/* PredicateList */ +extern pddl::PredicateList parse(const domain::ast::Predicates& predicates_node, Context& context); + +} + +#endif // LOKI_SRC_DOMAIN_PDDL_PARSER_PREDICATES_HPP_ diff --git a/src/domain/pddl/parser/requirements.cpp b/src/domain/pddl/parser/requirements.cpp new file mode 100644 index 00000000..7143cb83 --- /dev/null +++ b/src/domain/pddl/parser/requirements.cpp @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "requirements.hpp" + +#include "../../../../include/loki/domain/pddl/exceptions.hpp" + +using namespace loki::domain; + + +namespace loki { + +pddl::RequirementEnumSet parse(const ast::RequirementStrips&, Context& /*context*/) { + // Strips as the minimal requirement must not be tracked. + return { pddl::RequirementEnum::STRIPS }; +} + +pddl::RequirementEnumSet parse(const ast::RequirementTyping&, Context& context) { + // Track + context.references.track(pddl::RequirementEnum::TYPING); + return { pddl::RequirementEnum::TYPING }; +} + +pddl::RequirementEnumSet parse(const ast::RequirementNegativePreconditions&, Context& context) { + // Track + context.references.track(pddl::RequirementEnum::NEGATIVE_PRECONDITIONS); + return { pddl::RequirementEnum::NEGATIVE_PRECONDITIONS }; +} + +pddl::RequirementEnumSet parse(const ast::RequirementDisjunctivePreconditions&, Context& context) { + // Track + context.references.track(pddl::RequirementEnum::DISJUNCTIVE_PRECONDITIONS); + return { pddl::RequirementEnum::DISJUNCTIVE_PRECONDITIONS }; +} + +pddl::RequirementEnumSet parse(const ast::RequirementEquality&, Context& context) { + // Track + context.references.track(pddl::RequirementEnum::EQUALITY); + return { pddl::RequirementEnum::EQUALITY }; +} + +pddl::RequirementEnumSet parse(const ast::RequirementExistentialPreconditions&, Context& context) { + // Track + context.references.track(pddl::RequirementEnum::EXISTENTIAL_PRECONDITIONS); + return { pddl::RequirementEnum::EXISTENTIAL_PRECONDITIONS }; +} + +pddl::RequirementEnumSet parse(const ast::RequirementUniversalPreconditions&, Context& context) { + // Track + context.references.track(pddl::RequirementEnum::UNIVERSAL_PRECONDITIONS); + return { pddl::RequirementEnum::UNIVERSAL_PRECONDITIONS }; +} + +pddl::RequirementEnumSet parse(const ast::RequirementQuantifiedPreconditions&, Context& context) { + // Track + context.references.track(pddl::RequirementEnum::QUANTIFIED_PRECONDITIONS); + context.references.track(pddl::RequirementEnum::EXISTENTIAL_PRECONDITIONS); + context.references.track(pddl::RequirementEnum::UNIVERSAL_PRECONDITIONS); + return { pddl::RequirementEnum::QUANTIFIED_PRECONDITIONS, + pddl::RequirementEnum::EXISTENTIAL_PRECONDITIONS, + pddl::RequirementEnum::UNIVERSAL_PRECONDITIONS }; +} + +pddl::RequirementEnumSet parse(const ast::RequirementConditionalEffects&, Context& context) { + // Track + context.references.track(pddl::RequirementEnum::CONDITIONAL_EFFECTS); + return { pddl::RequirementEnum::CONDITIONAL_EFFECTS }; +} + +pddl::RequirementEnumSet parse(const ast::RequirementFluents&, Context& context) { + // Track + // FLUENTS as a composite must not be tracked + context.references.track(pddl::RequirementEnum::OBJECT_FLUENTS); + context.references.track(pddl::RequirementEnum::NUMERIC_FLUENTS); + return { pddl::RequirementEnum::FLUENTS, + pddl::RequirementEnum::OBJECT_FLUENTS, + pddl::RequirementEnum::NUMERIC_FLUENTS }; +} + +pddl::RequirementEnumSet parse(const ast::RequirementObjectFluents& node, Context& context) { + // Track + context.references.track(pddl::RequirementEnum::OBJECT_FLUENTS); + throw UnsupportedRequirementError( + pddl::RequirementEnum::OBJECT_FLUENTS, + context.scopes.get_error_handler()(node, "")); + + return { pddl::RequirementEnum::OBJECT_FLUENTS }; +} + +pddl::RequirementEnumSet parse(const ast::RequirementNumericFluents&, Context& context) { + // Track + context.references.track(pddl::RequirementEnum::NUMERIC_FLUENTS); + return { pddl::RequirementEnum::NUMERIC_FLUENTS }; +} + +pddl::RequirementEnumSet parse(const ast::RequirementAdl&, Context& context) { + // Track + // Strips as the minimal requirement must not be tracked. + // ADL as a composite must not be tracked + context.references.track(pddl::RequirementEnum::TYPING); + context.references.track(pddl::RequirementEnum::NEGATIVE_PRECONDITIONS); + context.references.track(pddl::RequirementEnum::DISJUNCTIVE_PRECONDITIONS); + context.references.track(pddl::RequirementEnum::EQUALITY); + context.references.track(pddl::RequirementEnum::QUANTIFIED_PRECONDITIONS); + context.references.track(pddl::RequirementEnum::EXISTENTIAL_PRECONDITIONS); + context.references.track(pddl::RequirementEnum::UNIVERSAL_PRECONDITIONS); + context.references.track(pddl::RequirementEnum::CONDITIONAL_EFFECTS); + return { pddl::RequirementEnum::ADL, + pddl::RequirementEnum::STRIPS, + pddl::RequirementEnum::TYPING, + pddl::RequirementEnum::NEGATIVE_PRECONDITIONS, + pddl::RequirementEnum::DISJUNCTIVE_PRECONDITIONS, + pddl::RequirementEnum::EQUALITY, + pddl::RequirementEnum::QUANTIFIED_PRECONDITIONS, + pddl::RequirementEnum::EXISTENTIAL_PRECONDITIONS, + pddl::RequirementEnum::UNIVERSAL_PRECONDITIONS, + pddl::RequirementEnum::CONDITIONAL_EFFECTS }; +} + +pddl::RequirementEnumSet parse(const ast::RequirementDurativeActions& node, Context& context) { + throw UnsupportedRequirementError( + pddl::RequirementEnum::DURATIVE_ACTIONS, + context.scopes.get_error_handler()(node, "")); + + // Track + context.references.track(pddl::RequirementEnum::DURATIVE_ACTIONS); + return { pddl::RequirementEnum::DURATIVE_ACTIONS }; +} + +pddl::RequirementEnumSet parse(const ast::RequirementDerivedPredicates& node, Context& context) { + throw UnsupportedRequirementError( + pddl::RequirementEnum::DERIVED_PREDICATES, + context.scopes.get_error_handler()(node, "")); + + // Track + context.references.track(pddl::RequirementEnum::DERIVED_PREDICATES); + return { pddl::RequirementEnum::DERIVED_PREDICATES }; +} + +pddl::RequirementEnumSet parse(const ast::RequirementTimedInitialLiterals& node, Context& context) { + throw UnsupportedRequirementError( + pddl::RequirementEnum::TIMED_INITIAL_LITERALS, + context.scopes.get_error_handler()(node, "")); + + // Track + context.references.track(pddl::RequirementEnum::TIMED_INITIAL_LITERALS); + context.references.track(pddl::RequirementEnum::DURATIVE_ACTIONS); + return { pddl::RequirementEnum::TIMED_INITIAL_LITERALS, + pddl::RequirementEnum::DURATIVE_ACTIONS }; +} + +pddl::RequirementEnumSet parse(const ast::RequirementPreferences& node, Context& context) { + throw UnsupportedRequirementError( + pddl::RequirementEnum::PREFERENCES, + context.scopes.get_error_handler()(node, "")); + + // Track + context.references.track(pddl::RequirementEnum::PREFERENCES); + return { pddl::RequirementEnum::PREFERENCES }; +} + +pddl::RequirementEnumSet parse(const ast::RequirementConstraints& node, Context& context) { + throw UnsupportedRequirementError( + pddl::RequirementEnum::CONSTRAINTS, + context.scopes.get_error_handler()(node, "")); + + // Track + context.references.track(pddl::RequirementEnum::CONSTRAINTS); + return { pddl::RequirementEnum::CONSTRAINTS }; + +} + +pddl::RequirementEnumSet parse(const ast::RequirementActionCosts&, Context& context) { + // Track + context.references.track(pddl::RequirementEnum::ACTION_COSTS); + return { pddl::RequirementEnum::ACTION_COSTS }; +} + +pddl::RequirementEnumSet parse(const ast::Requirement& node, Context& context) { + return boost::apply_visitor(RequirementVisitor(context), node); +} + +RequirementVisitor::RequirementVisitor(Context& context_) : context(context_) { } + +pddl::RequirementEnumSet parse(const ast::Requirements& requirements_node, Context& context) { + auto requirements = pddl::RequirementEnumSet(); + for (const auto& requirement : requirements_node.requirements) { + auto additional_requirements = parse(requirement, context); + requirements.insert(additional_requirements.begin(), additional_requirements.end()); + } + return requirements; +} + +} diff --git a/src/domain/pddl/parser/requirements.hpp b/src/domain/pddl/parser/requirements.hpp new file mode 100644 index 00000000..e2fbab89 --- /dev/null +++ b/src/domain/pddl/parser/requirements.hpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_DOMAIN_PDDL_PARSER_REQUIREMENTS_HPP_ +#define LOKI_SRC_DOMAIN_PDDL_PARSER_REQUIREMENTS_HPP_ + +#include "../../../../include/loki/common/ast/config.hpp" +#include "../../../../include/loki/domain/ast/ast.hpp" +#include "../../../../include/loki/domain/pddl/parser.hpp" + +using namespace loki::domain; + +namespace loki { + +/* Requirements */ +extern pddl::RequirementEnumSet parse(const domain::ast::Requirements& requirements_node, Context& context); +extern pddl::RequirementEnumSet parse(const domain::ast::RequirementStrips& node, Context& context); +extern pddl::RequirementEnumSet parse(const domain::ast::RequirementTyping& node, Context& context); +extern pddl::RequirementEnumSet parse(const domain::ast::RequirementNegativePreconditions& node, Context& context); +extern pddl::RequirementEnumSet parse(const domain::ast::RequirementDisjunctivePreconditions& node, Context& context); +extern pddl::RequirementEnumSet parse(const domain::ast::RequirementEquality& node, Context& context); +extern pddl::RequirementEnumSet parse(const domain::ast::RequirementExistentialPreconditions& node, Context& context); +extern pddl::RequirementEnumSet parse(const domain::ast::RequirementUniversalPreconditions& node, Context& context); +extern pddl::RequirementEnumSet parse(const domain::ast::RequirementQuantifiedPreconditions& node, Context& context); +extern pddl::RequirementEnumSet parse(const domain::ast::RequirementConditionalEffects& node, Context& context); +extern pddl::RequirementEnumSet parse(const domain::ast::RequirementFluents& node, Context& context); +extern pddl::RequirementEnumSet parse(const domain::ast::RequirementObjectFluents& node, Context& context); +extern pddl::RequirementEnumSet parse(const domain::ast::RequirementNumericFluents& node, Context& context); +extern pddl::RequirementEnumSet parse(const domain::ast::RequirementAdl& node, Context& context); +extern pddl::RequirementEnumSet parse(const domain::ast::RequirementDurativeActions& node, Context& context); +extern pddl::RequirementEnumSet parse(const domain::ast::RequirementDerivedPredicates& node, Context& context); +extern pddl::RequirementEnumSet parse(const domain::ast::RequirementTimedInitialLiterals& node, Context& context); +extern pddl::RequirementEnumSet parse(const domain::ast::RequirementPreferences& node, Context& context); +extern pddl::RequirementEnumSet parse(const domain::ast::RequirementConstraints& node, Context& context); +extern pddl::RequirementEnumSet parse(const domain::ast::RequirementActionCosts& node, Context& context); +extern pddl::RequirementEnumSet parse(const domain::ast::Requirement& node, Context& context); + +struct RequirementVisitor : boost::static_visitor { + Context& context; + + RequirementVisitor(Context& context_); + + template + pddl::RequirementEnumSet operator()(const Node& node) const { + return parse(node, context); + } +}; + +} + +#endif // LOKI_SRC_DOMAIN_PDDL_PARSER_REQUIREMENTS_HPP_ diff --git a/src/domain/pddl/parser/structure.cpp b/src/domain/pddl/parser/structure.cpp new file mode 100644 index 00000000..cbb7bbd6 --- /dev/null +++ b/src/domain/pddl/parser/structure.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "structure.hpp" + +#include "conditions.hpp" +#include "effects.hpp" +#include "parameters.hpp" +#include "common.hpp" + +#include "../../../../include/loki/domain/pddl/exceptions.hpp" +#include "../../../../include/loki/domain/pddl/action.hpp" +#include "../../../../include/loki/domain/pddl/derived_predicate.hpp" + + +namespace loki { + +std::tuple, std::optional> parse(const domain::ast::ActionBody& node, Context& context) { + std::optional condition; + if (node.precondition_goal_descriptor.has_value()) { + condition = parse(node.precondition_goal_descriptor.value(), context); + } + std::optional effect; + if (node.effect.has_value()) { + effect = parse(node.effect.value(), context); + } + return {condition, effect}; +} + +pddl::Action parse(const domain::ast::Action& node, Context& context) { + context.scopes.open_scope(); + auto name = parse(node.action_symbol.name); + auto parameter_list = boost::apply_visitor(ParameterListVisitor(context), node.typed_list_of_variables); + for (const auto& parameter : parameter_list) { + context.references.track(parameter->get_variable()); + } + auto [condition, effect] = parse(node.action_body, context); + // Check references + for (const auto& parameter : parameter_list) { + if (context.references.exists(parameter->get_variable())) { + const auto& [variable, position, error_handler] = context.scopes.get(parameter->get_variable()->get_name()).value(); + throw UnusedVariableError(variable->get_name(), error_handler(position.value(), "")); + } + } + + context.scopes.close_scope(); + const auto action = context.factories.actions.get_or_create(name, parameter_list, condition, effect); + context.positions.push_back(action, node); + return action; +} + +pddl::DerivedPredicate parse(const domain::ast::DerivedPredicate& node, Context& context) { + if (!context.requirements->test(pddl::RequirementEnum::DERIVED_PREDICATES)) { + throw UndefinedRequirementError(pddl::RequirementEnum::DERIVED_PREDICATES, context.scopes.get_error_handler()(node, "")); + } + context.references.untrack(pddl::RequirementEnum::DERIVED_PREDICATES); + context.scopes.open_scope(); + auto parameter_list = boost::apply_visitor(ParameterListVisitor(context), node.typed_list_of_variables); + for (const auto& parameter : parameter_list) { + context.references.track(parameter->get_variable()); + } + auto condition = parse(node.goal_descriptor, context); + const auto derived_predicate = context.factories.derived_predicates.get_or_create(parameter_list, condition); + // Check references + for (const auto& parameter : parameter_list) { + if (context.references.exists(parameter->get_variable())) { + const auto& [variable, position, error_handler] = context.scopes.get(parameter->get_variable()->get_name()).value(); + throw UnusedVariableError(variable->get_name(), error_handler(position.value(), "")); + } + } + + context.scopes.close_scope(); + context.positions.push_back(derived_predicate, node); + return derived_predicate; +} + + +StructureVisitor::StructureVisitor(Context& context_) + : context(context_) { } + + +boost::variant parse(const domain::ast::Structure& node, Context& context) { + return boost::apply_visitor(StructureVisitor(context), node); +} + + +} + diff --git a/src/domain/pddl/parser/structure.hpp b/src/domain/pddl/parser/structure.hpp new file mode 100644 index 00000000..730238d7 --- /dev/null +++ b/src/domain/pddl/parser/structure.hpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_DOMAIN_PDDL_PARSER_STRUCTURE_HPP_ +#define LOKI_SRC_DOMAIN_PDDL_PARSER_STRUCTURE_HPP_ + +#include "../../../../include/loki/domain/ast/ast.hpp" +#include "../../../../include/loki/domain/pddl/parser.hpp" +#include "../../../../include/loki/domain/pddl/declarations.hpp" +#include "../../../../include/loki/domain/pddl/derived_predicate.hpp" +#include "../../../../include/loki/domain/pddl/action.hpp" + + +namespace loki { + +extern std::tuple, std::optional> parse(const domain::ast::ActionBody& node, Context& context); + +extern pddl::Action parse(const domain::ast::Action& node, Context& context); + +extern pddl::DerivedPredicate parse(const domain::ast::DerivedPredicate& node, Context& context); + +struct StructureVisitor : boost::static_visitor> { + Context& context; + + StructureVisitor(Context& context_); + + template + boost::variant operator()(const Node& node) const { + return parse(node, context); + } +}; + +// TODO return durative action in the future as well. +extern boost::variant parse( + const domain::ast::Structure& node, Context& context); + + +} + +#endif // LOKI_SRC_DOMAIN_PDDL_PARSER_STRUCTURE_HPP_ diff --git a/src/domain/pddl/parser/types.cpp b/src/domain/pddl/parser/types.cpp new file mode 100644 index 00000000..7021e2a0 --- /dev/null +++ b/src/domain/pddl/parser/types.cpp @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "types.hpp" +#include "common.hpp" + +#include "../../../../include/loki/domain/pddl/exceptions.hpp" + +using namespace loki::domain; +using namespace std; + + +namespace loki { + +/* TypeDeclarationTypeVisitor */ + +TypeDeclarationTypeVisitor::TypeDeclarationTypeVisitor(Context& context_) + : context(context_) { } + +pddl::TypeList TypeDeclarationTypeVisitor::operator()(const ast::TypeObject& node) { + const auto type = context.factories.types.get_or_create("object"); + context.positions.push_back(type, node); + return { type }; +} + +pddl::TypeList TypeDeclarationTypeVisitor::operator()(const ast::TypeNumber& node) { + const auto type = context.factories.types.get_or_create("number"); + context.positions.push_back(type, node); + return { type }; +} + +pddl::TypeList TypeDeclarationTypeVisitor::operator()(const domain::ast::Name& node) { + auto name = parse(node); + const auto type = context.factories.types.get_or_create(name); + context.positions.push_back(type, node); + return { type }; +} + +pddl::TypeList TypeDeclarationTypeVisitor::operator()(const ast::TypeEither& node) { + // we flatten nested either types + pddl::TypeList type_list; + for (auto& child_node : node.types) { + auto types = boost::apply_visitor(*this, child_node); + type_list.insert(type_list.end(), types.begin(), types.end()); + } + return type_list; +} + +/* TypeReferenceTypeVisitor */ + +TypeReferenceTypeVisitor::TypeReferenceTypeVisitor(const Context& context_) + : context(context_) { } + +pddl::TypeList TypeReferenceTypeVisitor::operator()(const ast::TypeObject&) { + const auto binding = context.scopes.get("object"); + assert(binding.has_value()); + const auto& [type, _position, _error_handler] = binding.value(); + return {type}; +} + +pddl::TypeList TypeReferenceTypeVisitor::operator()(const ast::TypeNumber&) { + const auto binding = context.scopes.get("number"); + assert(binding.has_value()); + const auto& [type, _position, _error_handler] = binding.value(); + return {type}; +} + +pddl::TypeList TypeReferenceTypeVisitor::operator()(const domain::ast::Name& node) { + auto name = parse(node); + auto binding = context.scopes.get(name); + if (!binding.has_value()) { + throw UndefinedTypeError(name, context.scopes.get_error_handler()(node, "")); + } + const auto& [type, _position, _error_handler] = binding.value(); + context.positions.push_back(type, node); + return { type }; +} + +pddl::TypeList TypeReferenceTypeVisitor::operator()(const ast::TypeEither& node) { + // we flatten nested either types + auto type_list = pddl::TypeList(); + for (auto& child_node : node.types) { + auto types = boost::apply_visitor(*this, child_node); + type_list.insert(type_list.end(), types.begin(), types.end()); + } + return type_list; +} + +/* TypeDeclarationTypedListOfNamesVisitor */ +static void test_multiple_definition(const pddl::Type& type, const domain::ast::Name& node, const Context& context) { + const auto type_name = type->get_name(); + const auto binding = context.scopes.get(type_name); + if (binding.has_value()) { + const auto message_1 = context.scopes.get_error_handler()(node, "Defined here:"); + auto message_2 = std::string(""); + const auto& [_type, position, error_handler] = binding.value(); + if (position.has_value()) { + message_2 = error_handler(position.value(), "First defined here:"); + } + throw MultiDefinitionTypeError(type_name, message_1 + message_2); + } +} + + +static void test_reserved_type(const pddl::Type& type, const domain::ast::Name& node, const Context& context) { + if (type->get_name() == "object") { + throw ReservedTypeError("object", context.scopes.get_error_handler()(node, "")); + } + // We also reserve type name number although PDDL specification allows it. + // However, this allows using regular types as function types for simplicity. + if (type->get_name() == "number") { + throw ReservedTypeError("number", context.scopes.get_error_handler()(node, "")); + } +} + + +static void insert_context_information(const pddl::Type& type, const domain::ast::Name& node, Context& context) { + context.positions.push_back(type, node); + context.scopes.insert(type->get_name(), type, node); +} + + +static pddl::Type parse_type_definition(const domain::ast::Name& node, const pddl::TypeList& type_list, Context& context) { + const auto name = parse(node); + const auto type = context.factories.types.get_or_create(name, type_list); + test_reserved_type(type, node, context); + test_multiple_definition(type, node, context); + insert_context_information(type, node, context); + return type; +} + + +static pddl::TypeList parse_type_definitions(const std::vector& nodes, const pddl::TypeList& parent_type_list, Context& context) { + auto type_list = pddl::TypeList(); + for (const auto& node : nodes) { + type_list.push_back(parse_type_definition(node, parent_type_list, context)); + } + return type_list; +} + + +TypeDeclarationTypedListOfNamesVisitor::TypeDeclarationTypedListOfNamesVisitor(Context& context_) + : context(context_) { } + +pddl::TypeList TypeDeclarationTypedListOfNamesVisitor::operator()(const std::vector& name_nodes) { + // std::vector has single base type "object" + assert(context.scopes.get("object").has_value()); + const auto& [type_object, _position, _error_handler] = context.scopes.get("object").value(); + const auto type_list = parse_type_definitions(name_nodes, pddl::TypeList{type_object}, context); + return type_list; +} + +pddl::TypeList TypeDeclarationTypedListOfNamesVisitor::operator()(const ast::TypedListOfNamesRecursively& typed_list_of_names_recursively_node) { + // requires :typing + if (!context.requirements->test(pddl::RequirementEnum::TYPING)) { + throw UndefinedRequirementError(pddl::RequirementEnum::TYPING, context.scopes.get_error_handler()(typed_list_of_names_recursively_node, "")); + } + context.references.untrack(pddl::RequirementEnum::TYPING); + // TypedListOfNamesRecursively has user defined base types. + const auto parent_type_list = boost::apply_visitor(TypeDeclarationTypeVisitor(context), + typed_list_of_names_recursively_node.type); + auto type_list = parse_type_definitions(typed_list_of_names_recursively_node.names, parent_type_list, context); + // Recursively add types. + const auto additional_types = boost::apply_visitor(*this, typed_list_of_names_recursively_node.typed_list_of_names.get()); + type_list.insert(type_list.end(), additional_types.begin(), additional_types.end()); + return type_list; +} + +/* Other functions */ + +pddl::TypeList parse(const ast::Types& types_node, Context& context) { + return boost::apply_visitor(TypeDeclarationTypedListOfNamesVisitor(context), types_node.typed_list_of_names); +} + +} diff --git a/src/domain/pddl/parser/types.hpp b/src/domain/pddl/parser/types.hpp new file mode 100644 index 00000000..2d3b5c69 --- /dev/null +++ b/src/domain/pddl/parser/types.hpp @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_DOMAIN_PDDL_PARSER_TYPES_HPP_ +#define LOKI_SRC_DOMAIN_PDDL_PARSER_TYPES_HPP_ + +#include "../../../../include/loki/domain/ast/ast.hpp" +#include "../../../../include/loki/domain/pddl/parser.hpp" +#include "../../../../include/loki/domain/pddl/type.hpp" + + +namespace loki { + +class TypeDeclarationTypeVisitor : boost::static_visitor { +private: + Context& context; + +public: + TypeDeclarationTypeVisitor(Context& context_); + + pddl::TypeList operator()(const domain::ast::TypeObject& node); + + pddl::TypeList operator()(const domain::ast::TypeNumber& node); + + pddl::TypeList operator()(const domain::ast::Name& node); + + pddl::TypeList operator()(const domain::ast::TypeEither& node); +}; + +class TypeReferenceTypeVisitor : boost::static_visitor { +private: + const Context& context; + +public: + TypeReferenceTypeVisitor(const Context& context_); + + pddl::TypeList operator()(const domain::ast::TypeObject& node); + + pddl::TypeList operator()(const domain::ast::TypeNumber& node); + + pddl::TypeList operator()(const domain::ast::Name& node); + + pddl::TypeList operator()(const domain::ast::TypeEither& node); +}; + +class TypeDeclarationTypedListOfNamesVisitor : boost::static_visitor { +private: + Context& context; + +public: + TypeDeclarationTypedListOfNamesVisitor(Context& context_); + + pddl::TypeList operator()(const std::vector& nodes); + + pddl::TypeList operator()(const domain::ast::TypedListOfNamesRecursively& node); +}; + + +extern pddl::TypeList parse(const domain::ast::Types& node, Context& context); + +} + +#endif // LOKI_SRC_DOMAIN_PDDL_PARSER_TYPES_HPP_ diff --git a/src/domain/pddl/predicate.cpp b/src/domain/pddl/predicate.cpp new file mode 100644 index 00000000..bfd344da --- /dev/null +++ b/src/domain/pddl/predicate.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/domain/pddl/predicate.hpp" + +#include "../../../include/loki/domain/pddl/parameter.hpp" +#include "../../../include/loki/domain/pddl/variable.hpp" +#include "../../../include/loki/domain/pddl/type.hpp" +#include "../../../include/loki/common/hash.hpp" + +#include + +namespace loki::pddl { +PredicateImpl::PredicateImpl(int identifier, std::string name, ParameterList parameters) + : Base(identifier) + , m_name(std::move(name)) + , m_parameters(std::move(parameters)) +{ +} + +bool PredicateImpl::is_structurally_equivalent_to_impl(const PredicateImpl& other) const { + return (m_name == other.m_name) && (m_parameters == other.m_parameters); +} + +size_t PredicateImpl::hash_impl() const { + return hash_combine(m_name, hash_container(m_parameters)); +} + +void PredicateImpl::str_impl(std::ostringstream& out, const FormattingOptions& options) const { + str(out, options, true); +} + +void PredicateImpl::str(std::ostringstream& out, const FormattingOptions& options, bool typing_enabled) const { + out << "(" << m_name; + for (size_t i = 0; i < m_parameters.size(); ++i) { + out << " "; + m_parameters[i]->str(out, options, typing_enabled); + } + out << ")"; +} + +const std::string& PredicateImpl::get_name() const { + return m_name; +} + +const ParameterList& PredicateImpl::get_parameters() const { + return m_parameters; +} + +} + +namespace std { + bool less::operator()( + const loki::pddl::Predicate& left_predicate, + const loki::pddl::Predicate& right_predicate) const { + return *left_predicate < *right_predicate; + } + + std::size_t hash::operator()(const loki::pddl::PredicateImpl& predicate) const { + return predicate.hash_impl(); + } +} diff --git a/src/domain/pddl/requirements.cpp b/src/domain/pddl/requirements.cpp new file mode 100644 index 00000000..5f84fc79 --- /dev/null +++ b/src/domain/pddl/requirements.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/domain/pddl/requirements.hpp" +#include "../../../include/loki/common/hash.hpp" + +#include + + +namespace loki::pddl { + +std::unordered_map requirement_enum_to_string = { + { RequirementEnum::STRIPS, ":strips" }, + { RequirementEnum::TYPING, ":typing" }, + { RequirementEnum::NEGATIVE_PRECONDITIONS, ":negative-preconditions" }, + { RequirementEnum::DISJUNCTIVE_PRECONDITIONS, ":disjunctive-preconditions" }, + { RequirementEnum::EQUALITY, ":equality" }, + { RequirementEnum::EXISTENTIAL_PRECONDITIONS, ":existential-preconditions" }, + { RequirementEnum::UNIVERSAL_PRECONDITIONS, ":universal-preconditions" }, + { RequirementEnum::QUANTIFIED_PRECONDITIONS, ":quantified-preconditions" }, + { RequirementEnum::CONDITIONAL_EFFECTS, ":conditional-effects" }, + { RequirementEnum::FLUENTS, ":fluents" }, + { RequirementEnum::OBJECT_FLUENTS, ":object-fluents" }, + { RequirementEnum::NUMERIC_FLUENTS, ":numeric-fluents" }, + { RequirementEnum::ADL, ":adl" }, + { RequirementEnum::DURATIVE_ACTIONS, ":durative-actions" }, + { RequirementEnum::DERIVED_PREDICATES, ":derived-predicates" }, + { RequirementEnum::TIMED_INITIAL_LITERALS, ":timed-initial-literals" }, + { RequirementEnum::PREFERENCES, ":preferences" }, + { RequirementEnum::CONSTRAINTS, ":constraints" }, + { RequirementEnum::ACTION_COSTS, ":action-costs" } +}; + +const std::string& to_string(pddl::RequirementEnum requirement) { + assert(requirement_enum_to_string.count(requirement)); + return requirement_enum_to_string.at(requirement); +} + + +RequirementsImpl::RequirementsImpl(int identifier, RequirementEnumSet requirements) + : Base(identifier) + , m_requirements(std::move(requirements)) +{ +} + +bool RequirementsImpl::is_structurally_equivalent_to_impl(const RequirementsImpl& other) const { + return (m_requirements == other.m_requirements); +} + +size_t RequirementsImpl::hash_impl() const { + return hash_container(m_requirements); +} + +void RequirementsImpl::str_impl(std::ostringstream& out, const FormattingOptions& /*options*/) const { + out << "(:requirements "; + int i = 0; + for (const auto& requirement : m_requirements) { + if (i != 0) out << " "; + out << to_string(requirement); + ++i; + } + out << ")"; +} + +bool RequirementsImpl::test(RequirementEnum requirement) const { + return m_requirements.count(requirement); +} + +const RequirementEnumSet& RequirementsImpl::get_requirements() const { + return m_requirements; +} + +} + +namespace std { + bool less::operator()( + const loki::pddl::Requirements& left_requirements, + const loki::pddl::Requirements& right_requirements) const { + return *left_requirements < *right_requirements; + } + + std::size_t hash::operator()(const loki::pddl::RequirementsImpl& requirements) const { + return requirements.hash_impl(); + } +} diff --git a/src/domain/pddl/term.cpp b/src/domain/pddl/term.cpp new file mode 100644 index 00000000..276503bf --- /dev/null +++ b/src/domain/pddl/term.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/domain/pddl/term.hpp" + +#include "../../../include/loki/domain/pddl/object.hpp" +#include "../../../include/loki/domain/pddl/variable.hpp" +#include "../../../include/loki/common/hash.hpp" +#include "../../../include/loki/common/collections.hpp" + + +namespace loki::pddl { + + +/* TermObjectImpl */ +TermObjectImpl::TermObjectImpl(int identifier, Object object) + : Base(identifier), m_object(std::move(object)) { } + +bool TermObjectImpl::is_structurally_equivalent_to_impl(const TermObjectImpl& other) const { + if (this != &other) { + return m_object == other.m_object; + } + return true; +} + +size_t TermObjectImpl::hash_impl() const { + return hash_combine(m_object); +} + +void TermObjectImpl::str_impl(std::ostringstream& out, const FormattingOptions& /*options*/) const { + out << *m_object; +} + +const Object& TermObjectImpl::get_object() const { + return m_object; +} + + +/* TermVariableImpl */ +TermVariableImpl::TermVariableImpl(int identifier, Variable variable) + : Base(identifier), m_variable(std::move(variable)) { } + +bool TermVariableImpl::is_structurally_equivalent_to_impl(const TermVariableImpl& other) const { + if (this != &other) { + return m_variable == other.m_variable; + } + return true; +} + +size_t TermVariableImpl::hash_impl() const { + return hash_combine(m_variable); +} + +void TermVariableImpl::str_impl(std::ostringstream& out, const FormattingOptions& /*options*/) const { + out << *m_variable; +} + +const Variable& TermVariableImpl::get_variable() const { + return m_variable; +} + +} + +namespace std { + bool less::operator()( + const loki::pddl::Term& left_term, + const loki::pddl::Term& right_term) const { + return *left_term < *right_term; + } + + std::size_t hash::operator()(const loki::pddl::TermObjectImpl& term) const { + return term.hash_impl(); + } + + std::size_t hash::operator()(const loki::pddl::TermVariableImpl& term) const { + return term.hash_impl(); + } +} diff --git a/src/domain/pddl/type.cpp b/src/domain/pddl/type.cpp new file mode 100644 index 00000000..16687969 --- /dev/null +++ b/src/domain/pddl/type.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/domain/pddl/type.hpp" +#include "../../../include/loki/common/hash.hpp" +#include "../../../include/loki/common/collections.hpp" + + +namespace loki::pddl { +TypeImpl::TypeImpl(int identifier, std::string name, TypeList bases) + : Base(identifier) + , m_name(std::move(name)) + , m_bases(std::move(bases)) +{ +} + +bool TypeImpl::is_structurally_equivalent_to_impl(const TypeImpl& other) const { + return (m_name == other.m_name) && (get_sorted_vector(m_bases) == get_sorted_vector(other.m_bases)); +} + +size_t TypeImpl::hash_impl() const { + return hash_combine(m_name, hash_container(get_sorted_vector(m_bases))); +} + +void TypeImpl::str_impl(std::ostringstream& out, const FormattingOptions& /*options*/) const { + out << m_name; +} + +const std::string& TypeImpl::get_name() const { + return m_name; +} + +const TypeList& TypeImpl::get_bases() const { + return m_bases; +} + +} + +namespace std { + bool less::operator()( + const loki::pddl::Type& left_type, + const loki::pddl::Type& right_type) const { + return *left_type < *right_type; + } + + std::size_t hash::operator()(const loki::pddl::TypeImpl& type) const { + return type.hash_impl(); + } +} diff --git a/src/domain/pddl/unpacking_visitor.hpp b/src/domain/pddl/unpacking_visitor.hpp new file mode 100644 index 00000000..118c957a --- /dev/null +++ b/src/domain/pddl/unpacking_visitor.hpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_DOMAIN_PDDL_UNPACK_VISITOR_HPP_ +#define LOKI_SRC_DOMAIN_PDDL_UNPACK_VISITOR_HPP_ + +#include "../../../include/loki/common/ast/config.hpp" +#include "../../../include/loki/domain/pddl/parser.hpp" + +#include + +#include +#include +#include +#include + +namespace loki { + +/// @brief Given a variant this function allows visiting the variant +/// and pushing back in a respective vector. +/// In the constructor, there must be given a vector for all 1...N. +template +class UnpackingVisitor { +private: + std::tuple...> result; + +public: + UnpackingVisitor(Ts& ...result) + : result(std::make_tuple(std::ref(result)...)) { } + + template + void operator()(const T& element) { + std::get>>(result).get().push_back(element); + } +}; + +} + +#endif // LOKI_SRC_DOMAIN_PDDL_INSERT_VISITOR_HPP_ diff --git a/src/domain/pddl/variable.cpp b/src/domain/pddl/variable.cpp new file mode 100644 index 00000000..34b33f85 --- /dev/null +++ b/src/domain/pddl/variable.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2023 Dominik Drexler and Simon Stahlberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/domain/pddl/variable.hpp" +#include "../../../include/loki/common/hash.hpp" +#include "../../../include/loki/common/collections.hpp" + + +namespace loki::pddl { +VariableImpl::VariableImpl(int identifier, std::string name) + : Base(identifier) + , m_name(std::move(name)) +{ +} + +bool VariableImpl::is_structurally_equivalent_to_impl(const VariableImpl& other) const { + return (m_name == other.m_name); +} + +size_t VariableImpl::hash_impl() const { + return hash_combine(m_name); +} + +void VariableImpl::str_impl(std::ostringstream& out, const FormattingOptions& /*options*/) const { + out << m_name; +} + +const std::string& VariableImpl::get_name() const { + return m_name; +} + +} + + +namespace std { + bool less::operator()( + const loki::pddl::Variable& left_variable, + const loki::pddl::Variable& right_variable) const { + return *left_variable < *right_variable; + } + + std::size_t hash::operator()(const loki::pddl::VariableImpl& variable) const { + return variable.hash_impl(); + } +} diff --git a/src/problem/ast/ast_adapted.hpp b/src/problem/ast/ast_adapted.hpp new file mode 100644 index 00000000..5e6da436 --- /dev/null +++ b/src/problem/ast/ast_adapted.hpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_PROBLEM_AST_AST_ADAPTED_HPP_ +#define LOKI_SRC_PROBLEM_AST_AST_ADAPTED_HPP_ + +#include "../../../include/loki/problem/ast/ast.hpp" + +#include +#include + +// We need to tell fusion about our rexpr and rexpr_key_value +// to make them a first-class fusion citizens +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::BasicFunctionTerm, function_symbol, names) + +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::AtomicFormulaOfNamesPredicate, predicate, names) +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::AtomicFormulaOfNamesEquality, name_left, name_right) +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::Atom, atomic_formula_of_names) +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::NegatedAtom, atomic_formula_of_names) + +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::InitialElementLiteral, literal) +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::InitialElementTimedLiterals, number, literal) +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::InitialElementNumericFluentsTotalCost, function_symbol_total_cost, number) +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::InitialElementNumericFluentsGeneral, basic_function_term, number) + +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::MetricFunctionExpressionNumber, number) +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::MetricFunctionExpressionBinaryOperator, binary_operator, metric_function_expression_left, metric_function_expression_right) +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::MetricFunctionExpressionMultiOperator, multi_operator, metric_function_expression_first, metric_function_expression_remaining) +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::MetricFunctionExpressionMinus, metric_function_expression) +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::MetricFunctionExpressionBasicFunctionTerm, basic_function_term) +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::MetricFunctionExpressionPreferences, preference_name) + +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::PreferenceConstraintGoalDescriptorAnd, preference_constraint_goal_descriptors) +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::PreferenceConstraintGoalDescriptorForall, typed_list_of_variables, preference_constraint_goal_descriptor) +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::PreferenceConstraintGoalDescriptorPreference, preference_name, constraint_goal_descriptor) +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::PreferenceConstraintGoalDescriptorSimple, constraint_goal_descriptor) + +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::MetricSpecificationTotalCost, optimization_minimize, function_symbol_total_cost) +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::MetricSpecificationGeneral, optimization, metric_function_expression) + +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::ProblemName, name) +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::DomainName, name) +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::Objects, typed_list_of_names) +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::Initial, initial_elements) +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::Goal, precondition_goal_descriptor) +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::Constraints, preference_constraint_goal_descriptor) + +BOOST_FUSION_ADAPT_STRUCT(loki::problem::ast::Problem, problem_name, domain_name, requirements, objects, initial, goal, constraints, metric_specification) + + +#endif diff --git a/src/problem/ast/parser.hpp b/src/problem/ast/parser.hpp new file mode 100644 index 00000000..4f466afe --- /dev/null +++ b/src/problem/ast/parser.hpp @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_PROBLEM_AST_PARSER_HPP_ +#define LOKI_SRC_PROBLEM_AST_PARSER_HPP_ + +#include "../../../include/loki/problem/ast/ast.hpp" + +#include + + +namespace loki::problem { + namespace x3 = boost::spirit::x3; + + /////////////////////////////////////////////////////////////////////////// + // parser public interface for testing + /////////////////////////////////////////////////////////////////////////// + namespace parser { + struct BasicFunctionTermClass; + + struct AtomicFormulaOfNamesPredicateClass; + struct AtomicFormulaOfNamesEqualityClass; + struct AtomicFormulaOfNamesClass; + struct AtomClass; + struct NegatedAtomClass; + struct LiteralClass; + + struct InitialElementLiteralClass; + struct InitialElementTimedLiteralsClass; + struct InitialElementNumericFluentsTotalCostClass; + struct InitialElementNumericFluentsGeneralClass; + struct InitialElementClass; + + struct MetricFunctionExpressionClass; + struct MetricFunctionExpressionNumberClass; + struct MetricFunctionExpressionBinaryOperatorClass; + struct MetricFunctionExpressionMultiOperatorClass; + struct MetricFunctionExpressionMinusClass; + struct MetricFunctionExpressionBasicFunctionTermClass; + struct MetricFunctionExpressionTotalTimeClass; + struct MetricFunctionExpressionPreferencesClass; + + struct OptimizationMinimizeClass; + struct OptimizationMaximizeClass; + struct OptimizationClass; + struct MetricSpecificationTotalCostClass; + struct MetricSpecificationGeneralClass; + + struct PreferenceConstraintGoalDescriptorClass; + struct PreferenceConstraintGoalDescriptorAndClass; + struct PreferenceConstraintGoalDescriptorForallClass; + struct PreferenceConstraintGoalDescriptorPreferenceClass; + struct PreferenceConstraintGoalDescriptorSimpleClass; + + struct ProblemKeywordClass; + struct ProblemNameClass; + struct DomainNameClass; + struct ObjectsClass; + struct InitialClass; + struct GoalClass; + struct ConstraintsClass; + struct MetricSpecificationClass; + + + typedef x3::rule basic_function_term_type; + + typedef x3::rule atomic_formula_of_names_predicate_type; + typedef x3::rule atomic_formula_of_names_equality_type; + typedef x3::rule atomic_formula_of_names_type; + typedef x3::rule atom_type; + typedef x3::rule negated_atom_type; + typedef x3::rule literal_type; + + typedef x3::rule initial_element_literals_type; + typedef x3::rule initial_element_timed_literals_type; + typedef x3::rule initial_element_numeric_fluents_total_cost_type; + typedef x3::rule initial_element_numeric_fluents_general_type; + typedef x3::rule initial_element_type; + + typedef x3::rule metric_function_expression_type; + typedef x3::rule metric_function_expression_number_type; + typedef x3::rule metric_function_expression_binary_operator_type; + typedef x3::rule metric_function_expression_multi_operator_type; + typedef x3::rule metric_function_expression_minus_type; + typedef x3::rule metric_function_expression_basic_function_term_type; + typedef x3::rule metric_function_expression_total_time_type; + typedef x3::rule metric_function_expression_preferences_type; + + typedef x3::rule optimization_minimize_type; + typedef x3::rule optimization_maximize_type; + typedef x3::rule optimization_type; + typedef x3::rule metric_specification_total_cost_type; + typedef x3::rule metric_specification_general_type; + + typedef x3::rule preference_constraint_goal_descriptor_type; + typedef x3::rule preference_constraint_goal_descriptor_and_type; + typedef x3::rule preference_constraint_goal_descriptor_forall_type; + typedef x3::rule preference_constraint_goal_descriptor_preference_type; + typedef x3::rule preference_constraint_goal_descriptor_simple_type; + + typedef x3::rule problem_keyword_type; + typedef x3::rule problem_name_type; + typedef x3::rule domain_name_type; + typedef x3::rule objects_type; + typedef x3::rule initial_type; + typedef x3::rule goal_type; + typedef x3::rule constraints_type; + typedef x3::rule metric_specification_type; + + + BOOST_SPIRIT_DECLARE(basic_function_term_type) + + BOOST_SPIRIT_DECLARE(atomic_formula_of_names_predicate_type, atomic_formula_of_names_equality_type, + atomic_formula_of_names_type, atom_type, negated_atom_type, literal_type) + + BOOST_SPIRIT_DECLARE(initial_element_literals_type, initial_element_timed_literals_type, + initial_element_numeric_fluents_total_cost_type, initial_element_numeric_fluents_general_type, + initial_element_type) + + BOOST_SPIRIT_DECLARE(metric_function_expression_type, + metric_function_expression_binary_operator_type, + metric_function_expression_multi_operator_type, + metric_function_expression_minus_type, metric_function_expression_number_type, + metric_function_expression_basic_function_term_type, + metric_function_expression_total_time_type, metric_function_expression_preferences_type) + + BOOST_SPIRIT_DECLARE(optimization_minimize_type, optimization_maximize_type, optimization_type, + metric_specification_total_cost_type, metric_specification_general_type) + + BOOST_SPIRIT_DECLARE(preference_constraint_goal_descriptor_type, + preference_constraint_goal_descriptor_and_type, + preference_constraint_goal_descriptor_forall_type, + preference_constraint_goal_descriptor_preference_type, + preference_constraint_goal_descriptor_simple_type) + + BOOST_SPIRIT_DECLARE(problem_keyword_type, problem_name_type, domain_name_type, objects_type, + initial_type, goal_type, constraints_type, metric_specification_type) + } + + + parser::basic_function_term_type const& basic_function_term(); + + parser::atomic_formula_of_names_predicate_type const& atomic_formula_of_names_predicate(); + parser::atomic_formula_of_names_equality_type const& atomic_formula_of_names_equality(); + parser::atomic_formula_of_names_type const& atomic_formula_of_names(); + parser::atom_type const& atom(); + parser::negated_atom_type const& negated_atom(); + parser::literal_type const& literal(); + + parser::initial_element_literals_type const& initial_element_literals(); + parser::initial_element_timed_literals_type const& initial_element_timed_literals(); + parser::initial_element_numeric_fluents_total_cost_type const& initial_element_numeric_fluents_total_cost(); + parser::initial_element_numeric_fluents_general_type const& initial_element_numeric_fluents_general(); + parser::initial_element_type const& initial_element(); + + parser::metric_function_expression_type const& metric_function_expression(); + parser::metric_function_expression_number_type const& metric_function_expression_number(); + parser::metric_function_expression_binary_operator_type const& metric_function_expression_binary_operator(); + parser::metric_function_expression_multi_operator_type const& metric_function_expression_multi_operator(); + parser::metric_function_expression_minus_type const& metric_function_expression_minus(); + parser::metric_function_expression_basic_function_term_type const& metric_function_expression_basic_function_term(); + parser::metric_function_expression_total_time_type const& metric_function_expression_total_time(); + parser::metric_function_expression_preferences_type const& metric_function_expression_preferences(); + + parser::optimization_minimize_type const& optimization_minimize(); + parser::optimization_maximize_type const& optimization_maximize(); + parser::optimization_type const& optimization(); + parser::metric_specification_total_cost_type const& metric_specification_total_cost(); + parser::metric_specification_general_type const& metric_specification_general(); + + parser::preference_constraint_goal_descriptor_type const& preference_constraint_goal_descriptor(); + parser::preference_constraint_goal_descriptor_and_type const& preference_constraint_goal_descriptor_and(); + parser::preference_constraint_goal_descriptor_forall_type const& preference_constraint_goal_descriptor_forall(); + parser::preference_constraint_goal_descriptor_preference_type const& preference_constraint_goal_descriptor_preference(); + parser::preference_constraint_goal_descriptor_simple_type const& preference_constraint_goal_descriptor_simple(); + + parser::problem_keyword_type const& problem_keyword(); + parser::problem_name_type const& problem_name(); + parser::domain_name_type const& domain_name(); + parser::objects_type const& objects(); + parser::initial_type const& initial(); + parser::goal_type const& goal(); + parser::constraints_type const& constraints(); + parser::metric_specification_type const& metric_specification(); +} + +#endif diff --git a/src/problem/ast/parser_def.hpp b/src/problem/ast/parser_def.hpp new file mode 100644 index 00000000..80aa2813 --- /dev/null +++ b/src/problem/ast/parser_def.hpp @@ -0,0 +1,385 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_PROBLEM_AST_PARSER_DEF_HPP_ +#define LOKI_SRC_PROBLEM_AST_PARSER_DEF_HPP_ + +#include "ast_adapted.hpp" +#include "parser.hpp" + +#include "../../domain/ast/parser.hpp" +#include "../../../include/loki/problem/ast/ast.hpp" +#include "../../../include/loki/problem/ast/error_handler.hpp" +#include "../../../include/loki/problem/ast/parser.hpp" +#include "../../../include/loki/domain/ast/parser.hpp" + +#include +#include + + +namespace loki::problem::parser { + namespace x3 = boost::spirit::x3; + namespace ascii = boost::spirit::x3::ascii; + + using x3::lit; + using x3::lexeme; + using x3::eps; + using x3::int_; + using x3::double_; + using x3::expect; + using x3::no_skip; + + using ascii::alpha; + using ascii::alnum; + using ascii::char_; + using ascii::string; + + /////////////////////////////////////////////////////////////////////////// + // Rule IDs + /////////////////////////////////////////////////////////////////////////// + + + /////////////////////////////////////////////////////////////////////////// + // Rules + /////////////////////////////////////////////////////////////////////////// + + //domain_type const domain = "domain"; + + basic_function_term_type const basic_function_term = "basic_function_term"; + + atomic_formula_of_names_predicate_type const atomic_formula_of_names_predicate = "atomic_formula_of_names_predicate"; + atomic_formula_of_names_equality_type const atomic_formula_of_names_equality = "atomic_formula_of_names_equality"; + atomic_formula_of_names_type const atomic_formula_of_names = "atomic_formula_of_names"; + atom_type const atom = "atom"; + negated_atom_type const negated_atom = "negated_atom"; + literal_type const literal = "literal"; + + initial_element_literals_type const initial_element_literals = "initial_element_literals"; + initial_element_timed_literals_type const initial_element_timed_literals = "initial_element_timed_literals"; + initial_element_numeric_fluents_total_cost_type const initial_element_numeric_fluents_total_cost = "initial_element_numeric_fluents_total_cost"; + initial_element_numeric_fluents_general_type const initial_element_numeric_fluents_general = "initial_element_numeric_fluents_general"; + initial_element_type const initial_element = "initial_element"; + + metric_function_expression_type const metric_function_expression = "metric_function_expression"; + metric_function_expression_binary_operator_type const metric_function_expression_binary_operator = "metric_function_expression_binary_operator"; + metric_function_expression_multi_operator_type const metric_function_expression_multi_operator = "metric_function_expression_multi_operator"; + metric_function_expression_minus_type const metric_function_expression_minus = "metric_function_expression_minus"; + metric_function_expression_number_type const metric_function_expression_number = "metric_function_expression_number"; + metric_function_expression_basic_function_term_type const metric_function_expression_basic_function_term = "metric_function_expression_basic_function_term"; + metric_function_expression_total_time_type const metric_function_expression_total_time = "metric_function_expression_total_time"; + metric_function_expression_preferences_type const metric_function_expression_preferences = "metric_function_expression_preferences"; + + optimization_minimize_type const optimization_minimize = "optimization_minimize"; + optimization_maximize_type const optimization_maximize = "optimization_maximize"; + optimization_type const optimization = "optimization"; + metric_specification_total_cost_type const metric_specification_total_cost = "metric_specification_total_cost"; + metric_specification_general_type const metric_specification_general = "metric_specification_general"; + + preference_constraint_goal_descriptor_type const preference_constraint_goal_descriptor = "preference_constraint_goal_descriptor"; + preference_constraint_goal_descriptor_and_type const preference_constraint_goal_descriptor_and = "preference_constraint_goal_descriptor_and"; + preference_constraint_goal_descriptor_forall_type const preference_constraint_goal_descriptor_forall = "preference_constraint_goal_descriptor_forall"; + preference_constraint_goal_descriptor_preference_type const preference_constraint_goal_descriptor_preference = "preference_constraint_goal_descriptor_preference"; + preference_constraint_goal_descriptor_simple_type const preference_constraint_goal_descriptor_simple = "preference_constraint_goal_descriptor_simple"; + + problem_keyword_type const problem_keyword = "problem"; + problem_name_type const problem_name = "problem_name"; + domain_name_type const domain_name = "domain_name"; + objects_type const objects = "objects"; + initial_type const initial = "initial"; + goal_type const goal = "goal"; + constraints_type const constraints = "constraints"; + metric_specification_type const metric_specification = "metric_specification"; + + problem_type const problem = "problem"; + + + /////////////////////////////////////////////////////////////////////////// + // Grammar + /////////////////////////////////////////////////////////////////////////// + + const auto basic_function_term_def = ((lit('(') > domain::function_symbol() > *domain::name()) > lit(')')) | (domain::function_symbol() > x3::attr(std::vector{})); + + const auto atomic_formula_of_names_predicate_def = (lit('(') >> domain::predicate()) > *domain::name() > lit(')'); + const auto atomic_formula_of_names_equality_def = (lit('(') >> lit('=')) > domain::name() > domain::name() > lit(')'); + const auto atomic_formula_of_names_def = atomic_formula_of_names_equality | atomic_formula_of_names_predicate; + const auto atom_def = atomic_formula_of_names; + const auto negated_atom_def = lit('(') >> domain::keyword_lit("not") > atomic_formula_of_names >> lit(')'); + const auto literal_def = atom | negated_atom; + + const auto initial_element_literals_def = literal; + const auto initial_element_timed_literals_def = (lit('(') >> lit("at") >> domain::number()) > literal > lit(')'); + const auto initial_element_numeric_fluents_total_cost_def = (lit('(') >> lit('=') >> lit('(') >> domain::function_symbol_total_cost()) > lit(')') > domain::number() > lit(')'); + const auto initial_element_numeric_fluents_general_def = (lit('(') >> lit('=') >> basic_function_term) > domain::number() > lit(')'); + const auto initial_element_def = initial_element_timed_literals | initial_element_numeric_fluents_total_cost + | initial_element_numeric_fluents_general | initial_element_literals; + + + const auto metric_function_expression_binary_operator_def = (lit('(') >> domain::binary_operator() >> metric_function_expression >> metric_function_expression) > lit(')'); + const auto metric_function_expression_multi_operator_def = (lit('(') >> domain::multi_operator() >> metric_function_expression >> +metric_function_expression) > lit(')'); + const auto metric_function_expression_minus_def = (lit('(') >> lit('-')) > metric_function_expression > lit(')'); + const auto metric_function_expression_preferences_def = (lit('(') >> domain::keyword_lit("is-violated")) > domain::preference_name() > lit(')'); + const auto metric_function_expression_basic_function_term_def = basic_function_term; + const auto metric_function_expression_total_time_def = domain::keyword_lit("total-time") > x3::attr(ast::MetricFunctionExpressionTotalTime{}); + const auto metric_function_expression_number_def = domain::number(); + const auto metric_function_expression_def = metric_function_expression_binary_operator + | metric_function_expression_multi_operator | metric_function_expression_minus + | metric_function_expression_preferences | metric_function_expression_basic_function_term + | metric_function_expression_total_time | metric_function_expression_number; + + const auto optimization_minimize_def = domain::keyword_lit("minimize") > x3::attr(ast::OptimizationMinimize{}); + const auto optimization_maximize_def = domain::keyword_lit("maximize") > x3::attr(ast::OptimizationMaximize{}); + const auto optimization_def = optimization_minimize | optimization_maximize; + const auto metric_specification_total_cost_def = optimization_minimize >> lit('(') >> domain::function_symbol_total_cost() > lit(')'); + const auto metric_specification_general_def = optimization >> metric_function_expression; + + const auto preference_constraint_goal_descriptor_and_def = (lit('(') >> domain::keyword_lit("and")) > *preference_constraint_goal_descriptor > lit(')'); + const auto preference_constraint_goal_descriptor_forall_def = (lit('(') >> domain::keyword_lit("forall")) > domain::typed_list_of_variables() > preference_constraint_goal_descriptor > lit(')'); + const auto preference_constraint_goal_descriptor_preference_def = (lit('(') >> domain::keyword_lit("preference") > (-domain::preference_name())) > domain::constraint_goal_descriptor() > lit(')'); + const auto preference_constraint_goal_descriptor_simple_def = domain::constraint_goal_descriptor(); + const auto preference_constraint_goal_descriptor_def = preference_constraint_goal_descriptor_and | preference_constraint_goal_descriptor_forall + | preference_constraint_goal_descriptor_preference | preference_constraint_goal_descriptor_simple; + + const auto problem_keyword_def = domain::keyword_lit("problem"); + const auto problem_name_def = lit('(') > problem_keyword > domain::name() > lit(')'); + const auto domain_name_def = (lit('(') >> domain::keyword_lit(":domain")) > domain::name() > lit(')'); + const auto objects_def = (lit('(') >> domain::keyword_lit(":objects")) > domain::typed_list_of_names() > lit(')'); + const auto initial_def = (lit('(') >> domain::keyword_lit(":init")) > *initial_element > lit(')'); + const auto goal_def = (lit('(') >> domain::keyword_lit(":goal")) > domain::precondition_goal_descriptor() > lit(')'); + const auto constraints_def = (lit('(') >> domain::keyword_lit(":constraints")) > preference_constraint_goal_descriptor > lit(')'); + const auto metric_specification_def = (lit('(') >> domain::keyword_lit(":metric")) > (metric_specification_total_cost | metric_specification_general) > lit(')'); + + const auto problem_def = lit('(') > domain::define_keyword() + > problem_name + > domain_name + > -domain::requirements() + > -objects + > initial + > goal + > -constraints + > -metric_specification + > lit(')'); + + + BOOST_SPIRIT_DEFINE(basic_function_term) + + BOOST_SPIRIT_DEFINE(atomic_formula_of_names_predicate, atomic_formula_of_names_equality, + atomic_formula_of_names, atom, negated_atom, literal) + + BOOST_SPIRIT_DEFINE(initial_element_literals, initial_element_timed_literals, + initial_element_numeric_fluents_total_cost, initial_element_numeric_fluents_general, + initial_element) + + BOOST_SPIRIT_DEFINE(metric_function_expression, + metric_function_expression_number, + metric_function_expression_binary_operator, + metric_function_expression_multi_operator, + metric_function_expression_minus, + metric_function_expression_basic_function_term, + metric_function_expression_total_time, metric_function_expression_preferences) + + BOOST_SPIRIT_DEFINE(optimization_minimize, optimization_maximize, optimization, metric_specification_total_cost, metric_specification_general) + + BOOST_SPIRIT_DEFINE(preference_constraint_goal_descriptor, + preference_constraint_goal_descriptor_and, + preference_constraint_goal_descriptor_forall, + preference_constraint_goal_descriptor_preference, + preference_constraint_goal_descriptor_simple) + + BOOST_SPIRIT_DEFINE(problem_keyword, problem_name, domain_name, objects, + initial, goal, constraints, metric_specification, problem) + + /////////////////////////////////////////////////////////////////////////// + // Annotation and Error handling + /////////////////////////////////////////////////////////////////////////// + + struct BasicFunctionTermArityGreaterZeroClass : x3::annotate_on_success {}; + struct BasicFunctionTermArityZeroClass : x3::annotate_on_success {}; + struct BasicFunctionTermClass : x3::annotate_on_success {}; + + struct AtomicFormulaOfNamesPredicateClass : x3::annotate_on_success {}; + struct AtomicFormulaOfNamesEqualityClass : x3::annotate_on_success {}; + struct AtomicFormulaOfNamesClass : x3::annotate_on_success {}; + struct AtomClass : x3::annotate_on_success {}; + struct NegatedAtomClass : x3::annotate_on_success {}; + struct LiteralClass : x3::annotate_on_success {}; + + struct InitialElementLiteralClass : x3::annotate_on_success {}; + struct InitialElementTimedLiteralsClass : x3::annotate_on_success {}; + struct InitialElementNumericFluentsTotalCostClass : x3::annotate_on_success {}; + struct InitialElementNumericFluentsGeneralClass : x3::annotate_on_success {}; + struct InitialElementClass : x3::annotate_on_success {}; + + struct MetricFunctionExpressionClass : x3::annotate_on_success {}; + struct MetricFunctionExpressionNumberClass : x3::annotate_on_success {}; + struct MetricFunctionExpressionBinaryOperatorClass : x3::annotate_on_success {}; + struct MetricFunctionExpressionMultiOperatorClass : x3::annotate_on_success {}; + struct MetricFunctionExpressionMinusClass : x3::annotate_on_success {}; + struct MetricFunctionExpressionBasicFunctionTermClass : x3::annotate_on_success {}; + struct MetricFunctionExpressionTotalTimeClass : x3::annotate_on_success {}; + struct MetricFunctionExpressionPreferencesClass : x3::annotate_on_success {}; + + struct OptimizationMinimizeClass : x3::annotate_on_success {}; + struct OptimizationMaximizeClass : x3::annotate_on_success {}; + struct OptimizationClass : x3::annotate_on_success {}; + struct MetricSpecificationTotalCostClass : x3::annotate_on_success {}; + struct MetricSpecificationGeneralClass : x3::annotate_on_success {}; + + struct PreferenceConstraintGoalDescriptorClass : x3::annotate_on_success {}; + struct PreferenceConstraintGoalDescriptorAndClass : x3::annotate_on_success {}; + struct PreferenceConstraintGoalDescriptorForallClass : x3::annotate_on_success {}; + struct PreferenceConstraintGoalDescriptorPreferenceClass : x3::annotate_on_success {}; + struct PreferenceConstraintGoalDescriptorSimpleClass : x3::annotate_on_success {}; + + struct ProblemNameClass : x3::annotate_on_success {}; + struct DomainNameClass : x3::annotate_on_success {}; + struct ObjectsClass : x3::annotate_on_success {}; + struct InitialClass : x3::annotate_on_success {}; + struct GoalClass : x3::annotate_on_success {}; + struct ConstraintsClass : x3::annotate_on_success {}; + struct MetricSpecificationClass : x3::annotate_on_success {}; + + struct ProblemClass : x3::annotate_on_success, error_handler_problem {}; +} + +namespace loki::problem +{ + parser::basic_function_term_type const& basic_function_term() { + return parser::basic_function_term; + } + + parser::atomic_formula_of_names_predicate_type const& atomic_formula_of_names_predicate() { + return parser::atomic_formula_of_names_predicate; + } + parser::atomic_formula_of_names_equality_type const& atomic_formula_of_names_equality() { + return parser::atomic_formula_of_names_equality; + } + parser::atomic_formula_of_names_type const& atomic_formula_of_names() { + return parser::atomic_formula_of_names; + } + parser::atom_type const& atom() { + return parser::atom; + } + parser::negated_atom_type const& negated_atom() { + return parser::negated_atom; + } + parser::literal_type const& literal() { + return parser::literal; + } + + parser::initial_element_literals_type const& initial_element_literals() { + return parser::initial_element_literals; + } + parser::initial_element_timed_literals_type const& initial_element_timed_literals() { + return parser::initial_element_timed_literals; + } + parser::initial_element_numeric_fluents_total_cost_type const& initial_element_numeric_fluents_total_cost() { + return parser::initial_element_numeric_fluents_total_cost; + } + parser::initial_element_numeric_fluents_general_type const& initial_element_numeric_fluents_general() { + return parser::initial_element_numeric_fluents_general; + } + parser::initial_element_type const& initial_element() { + return parser::initial_element; + } + + parser::metric_function_expression_type const& metric_function_expression() { + return parser::metric_function_expression; + } + parser::metric_function_expression_number_type const& metric_function_expression_number() { + return parser::metric_function_expression_number; + } + parser::metric_function_expression_binary_operator_type const& metric_function_expression_binary_operator() { + return parser::metric_function_expression_binary_operator; + } + parser::metric_function_expression_multi_operator_type const& metric_function_expression_multi_operator() { + return parser::metric_function_expression_multi_operator; + } + parser::metric_function_expression_minus_type const& metric_function_expression_minus() { + return parser::metric_function_expression_minus; + } + parser::metric_function_expression_basic_function_term_type const& metric_function_expression_basic_function_term() { + return parser::metric_function_expression_basic_function_term; + } + parser::metric_function_expression_total_time_type const& metric_function_expression_total_time() { + return parser::metric_function_expression_total_time; + } + parser::metric_function_expression_preferences_type const& metric_function_expression_preferences() { + return parser::metric_function_expression_preferences; + } + + parser::optimization_minimize_type const& optimization_minimize() { + return parser::optimization_minimize; + } + parser::optimization_maximize_type const& optimization_maximize() { + return parser::optimization_maximize; + } + parser::optimization_type const& optimization() { + return parser::optimization; + } + parser::metric_specification_total_cost_type const& metric_specification_total_cost() { + return parser::metric_specification_total_cost; + } + parser::metric_specification_general_type const& metric_specification_general() { + return parser::metric_specification_general; + } + + parser::preference_constraint_goal_descriptor_type const& preference_constraint_goal_descriptor() { + return parser::preference_constraint_goal_descriptor; + } + parser::preference_constraint_goal_descriptor_and_type const& preference_constraint_goal_descriptor_and() { + return parser::preference_constraint_goal_descriptor_and; + } + parser::preference_constraint_goal_descriptor_forall_type const& preference_constraint_goal_descriptor_forall() { + return parser::preference_constraint_goal_descriptor_forall; + } + parser::preference_constraint_goal_descriptor_preference_type const& preference_constraint_goal_descriptor_preference() { + return parser::preference_constraint_goal_descriptor_preference; + } + parser::preference_constraint_goal_descriptor_simple_type const& preference_constraint_goal_descriptor_simple() { + return parser::preference_constraint_goal_descriptor_simple; + } + + parser::problem_keyword_type const& problem_keyword() { + return parser::problem_keyword; + } + parser::problem_name_type const& problem_name() { + return parser::problem_name; + } + parser::domain_name_type const& domain_name() { + return parser::domain_name; + } + parser::objects_type const& objects() { + return parser::objects; + } + parser::initial_type const& initial() { + return parser::initial; + } + parser::goal_type const& goal() { + return parser::goal; + } + parser::constraints_type const& constraints() { + return parser::constraints; + } + parser::metric_specification_type const& metric_specification() { + return parser::metric_specification; + } + parser::problem_type const& problem() { + return parser::problem; + } +} + +#endif diff --git a/src/problem/ast/parser_instantiations.cpp b/src/problem/ast/parser_instantiations.cpp new file mode 100644 index 00000000..4920dde4 --- /dev/null +++ b/src/problem/ast/parser_instantiations.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "parser_def.hpp" + +#include "../../../include/loki/common/ast/config.hpp" + + +namespace loki::problem::parser +{ + using iterator_type = loki::iterator_type; + using phrase_context_type = loki::phrase_context_type; + using context_type = loki::context_type; + + BOOST_SPIRIT_INSTANTIATE(basic_function_term_type, iterator_type, context_type) + + BOOST_SPIRIT_INSTANTIATE(atomic_formula_of_names_predicate_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(atomic_formula_of_names_equality_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(atomic_formula_of_names_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(atom_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(negated_atom_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(literal_type, iterator_type, context_type) + + BOOST_SPIRIT_INSTANTIATE(initial_element_literals_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(initial_element_timed_literals_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(initial_element_numeric_fluents_total_cost_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(initial_element_numeric_fluents_general_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(initial_element_type, iterator_type, context_type) + + BOOST_SPIRIT_INSTANTIATE(metric_function_expression_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(metric_function_expression_number_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(metric_function_expression_binary_operator_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(metric_function_expression_multi_operator_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(metric_function_expression_minus_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(metric_function_expression_basic_function_term_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(metric_function_expression_total_time_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(metric_function_expression_preferences_type, iterator_type, context_type) + + BOOST_SPIRIT_INSTANTIATE(optimization_minimize_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(optimization_maximize_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(optimization_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(metric_specification_total_cost_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(metric_specification_general_type, iterator_type, context_type) + + BOOST_SPIRIT_INSTANTIATE(preference_constraint_goal_descriptor_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(preference_constraint_goal_descriptor_and_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(preference_constraint_goal_descriptor_forall_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(preference_constraint_goal_descriptor_preference_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(preference_constraint_goal_descriptor_simple_type, iterator_type, context_type) + + BOOST_SPIRIT_INSTANTIATE(problem_keyword_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(problem_name_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(domain_name_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(objects_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(initial_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(goal_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(constraints_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(metric_specification_type, iterator_type, context_type) + BOOST_SPIRIT_INSTANTIATE(problem_type, iterator_type, context_type) +} diff --git a/src/problem/ast/printer.cpp b/src/problem/ast/printer.cpp new file mode 100644 index 00000000..c909edeb --- /dev/null +++ b/src/problem/ast/printer.cpp @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/problem/ast/printer.hpp" + +#include "../../../include/loki/domain/ast/printer.hpp" + +#include + +using namespace std; + + +namespace loki { + + // Printer for std::vector + template + inline std::string parse_text(const std::vector& nodes, const FormattingOptions& options); + + // Printer for boost::variant + class NodeVisitorPrinter : public boost::static_visitor { + private: + const FormattingOptions* options; + + public: + NodeVisitorPrinter(const FormattingOptions& options) : options(&options) { } + + template + std::string operator()(const Node& node) const + { + return parse_text(node, *options); + } + }; + + + string parse_text(const problem::ast::BasicFunctionTerm& node, const FormattingOptions& options) { + std::stringstream ss; + if (node.names.size() > 0) { + ss << "(" << parse_text(node.function_symbol, options) << " " << parse_text(node.names, options) << ")"; + } else { + ss << parse_text(node.function_symbol, options); + } + return ss.str(); + } + + + string parse_text(const problem::ast::AtomicFormulaOfNamesPredicate& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(" << parse_text(node.predicate, options) << " " << parse_text(node.names, options) << ")"; + return ss.str(); + } + + string parse_text(const problem::ast::AtomicFormulaOfNamesEquality& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(" << "= " << parse_text(node.name_left, options) << " " << parse_text(node.name_right, options) << ")"; + return ss.str(); + } + + string parse_text(const problem::ast::AtomicFormulaOfNames& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + string parse_text(const problem::ast::Atom& node, const FormattingOptions& options) { + return parse_text(node.atomic_formula_of_names, options); + } + + string parse_text(const problem::ast::NegatedAtom& node, const FormattingOptions& options) { + std::stringstream ss; + ss << "(not " << parse_text(node.atomic_formula_of_names, options) << ")"; + return ss.str(); + } + + string parse_text(const problem::ast::Literal& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + + string parse_text(const problem::ast::InitialElementLiteral& node, const FormattingOptions& options) { + return parse_text(node.literal, options); + } + + string parse_text(const problem::ast::InitialElementTimedLiterals& node, const FormattingOptions& options) { + stringstream ss; + ss << "(at " << parse_text(node.number, options) << " " << parse_text(node.literal, options) << ")"; + return ss.str(); + } + + string parse_text(const problem::ast::InitialElementNumericFluentsTotalCost& node, const FormattingOptions& options) { + stringstream ss; + ss << "(= " << parse_text(node.function_symbol_total_cost, options) << " " << parse_text(node.number, options) << ")"; + return ss.str(); + } + + string parse_text(const problem::ast::InitialElementNumericFluentsGeneral& node, const FormattingOptions& options) { + stringstream ss; + ss << "(= " << parse_text(node.basic_function_term, options) << " " << parse_text(node.number, options) << ")"; + return ss.str(); + } + + string parse_text(const problem::ast::InitialElement& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + + string parse_text(const problem::ast::MetricFunctionExpression& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + string parse_text(const problem::ast::MetricFunctionExpressionNumber& node, const FormattingOptions& options) { + return parse_text(node.number, options); + } + + string parse_text(const problem::ast::MetricFunctionExpressionBinaryOperator& node, const FormattingOptions& options) { + stringstream ss; + ss << "(" << parse_text(node.binary_operator, options) << " " + << parse_text(node.metric_function_expression_left, options) << " " + << parse_text(node.metric_function_expression_right, options) << ")"; + return ss.str(); + } + + string parse_text(const problem::ast::MetricFunctionExpressionMultiOperator& node, const FormattingOptions& options) { + stringstream ss; + ss << "(" << parse_text(node.multi_operator, options) << " " + << parse_text(node.metric_function_expression_first, options) << " " + << parse_text(node.metric_function_expression_remaining, options) << ")"; + return ss.str(); + } + + string parse_text(const problem::ast::MetricFunctionExpressionMinus& node, const FormattingOptions& options) { + stringstream ss; + ss << "(-" << parse_text(node.metric_function_expression, options) << ")"; + return ss.str(); + } + + string parse_text(const problem::ast::MetricFunctionExpressionBasicFunctionTerm& node, const FormattingOptions& options) { + return parse_text(node.basic_function_term, options); + } + + string parse_text(const problem::ast::MetricFunctionExpressionTotalTime&, const FormattingOptions&) { return "total-time";} + + string parse_text(const problem::ast::MetricFunctionExpressionPreferences& node, const FormattingOptions& options) { + stringstream ss; + ss << "(" << "is-violated " << parse_text(node.preference_name, options) << ")"; + return ss.str(); + } + + + string parse_text(const problem::ast::OptimizationMinimize&, const FormattingOptions&) { return "minimize"; } + string parse_text(const problem::ast::OptimizationMaximize&, const FormattingOptions&) { return "maximize"; } + string parse_text(const problem::ast::Optimization& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + std::string parse_text(const problem::ast::MetricSpecificationTotalCost& node, const FormattingOptions& options) { + stringstream ss; + ss << "(:metric " << parse_text(node.optimization_minimize, options) << " " + << parse_text(node.function_symbol_total_cost, options) << ")"; + return ss.str(); + } + + std::string parse_text(const problem::ast::MetricSpecificationGeneral& node, const FormattingOptions& options) { + stringstream ss; + ss << "(:metric " << parse_text(node.optimization, options) << " " + << parse_text(node.metric_function_expression, options) << ")"; + return ss.str(); + } + + + + string parse_text(const problem::ast::PreferenceConstraintGoalDescriptor& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + string parse_text(const problem::ast::PreferenceConstraintGoalDescriptorAnd& node, const FormattingOptions& options) { + stringstream ss; + ss << "(and " << parse_text(node.preference_constraint_goal_descriptors, options) << ")"; + return ss.str(); + } + + string parse_text(const problem::ast::PreferenceConstraintGoalDescriptorForall& node, const FormattingOptions& options) { + stringstream ss; + ss << "(forall " << parse_text(node.typed_list_of_variables, options) << " " + << parse_text(node.preference_constraint_goal_descriptor, options) << ")"; + return ss.str(); + } + + string parse_text(const problem::ast::PreferenceConstraintGoalDescriptorPreference& node, const FormattingOptions& options) { + stringstream ss; + ss << "(preference "; + if (node.preference_name.has_value()) { + ss << parse_text(node.preference_name.value(), options) << " "; + } + ss << parse_text(node.constraint_goal_descriptor, options) << ")"; + return ss.str(); + } + + string parse_text(const problem::ast::PreferenceConstraintGoalDescriptorSimple& node, const FormattingOptions& options) { + return parse_text(node.constraint_goal_descriptor, options); + } + + + string parse_text(const problem::ast::ProblemName& node, const FormattingOptions& options) { + stringstream ss; + ss << "(problem " << parse_text(node.name, options) << ")"; + return ss.str(); + } + + string parse_text(const problem::ast::DomainName& node, const FormattingOptions& options) { + stringstream ss; + ss << "(:domain " << parse_text(node.name, options) << ")"; + return ss.str(); + } + + string parse_text(const problem::ast::Objects& node, const FormattingOptions& options) { + stringstream ss; + ss << "(:objects " << parse_text(node.typed_list_of_names, options) << ")"; + return ss.str(); + } + + string parse_text(const problem::ast::Initial& node, const FormattingOptions& options) { + stringstream ss; + ss << "(:init " << parse_text(node.initial_elements, options) << ")"; + return ss.str(); + } + + string parse_text(const problem::ast::Goal& node, const FormattingOptions& options) { + stringstream ss; + ss << "(:goal " << parse_text(node.precondition_goal_descriptor, options) << ")"; + return ss.str(); + } + + string parse_text(const problem::ast::Constraints& node, const FormattingOptions& options) { + stringstream ss; + ss << "(:constraints " << parse_text(node.preference_constraint_goal_descriptor, options) << ")"; + return ss.str(); + } + + string parse_text(const problem::ast::MetricSpecification& node, const FormattingOptions& options) { + return boost::apply_visitor(NodeVisitorPrinter(options), node); + } + + + string parse_text(const problem::ast::Problem& node, const FormattingOptions& options) { + stringstream ss; + ss << string(options.indent, ' ') << "(define " << parse_text(node.problem_name, options) << "\n"; + auto nested_options = FormattingOptions{options.indent + options.add_indent, options.add_indent}; + ss << string(nested_options.indent, ' ') << parse_text(node.domain_name, nested_options) << "\n"; + if (node.requirements.has_value()) { + ss << string(nested_options.indent, ' ') << parse_text(node.requirements.value(), nested_options) << "\n"; + } + if (node.objects.has_value()) { + ss << string(nested_options.indent, ' ') << parse_text(node.objects.value(), nested_options) << "\n"; + } + ss << string(nested_options.indent, ' ') << parse_text(node.initial, nested_options) << "\n"; + ss << string(nested_options.indent, ' ') << parse_text(node.goal, nested_options) << "\n"; + if (node.constraints.has_value()) { + ss << string(nested_options.indent, ' ') << parse_text(node.constraints.value(), nested_options) << "\n"; + } + if (node.metric_specification.has_value()) { + ss << string(nested_options.indent, ' ') << parse_text(node.metric_specification.value(), nested_options) << "\n"; + } + ss << string(options.indent, ' ') << ")"; + return ss.str(); + } + + template + inline std::string parse_text(const std::vector& nodes, const FormattingOptions& options) + { + std::stringstream ss; + for (size_t i = 0; i < nodes.size(); ++i) + { + if (i != 0) + ss << " "; + ss << parse_text(nodes[i], options); + } + return ss.str(); + } +} diff --git a/src/problem/parser.cpp b/src/problem/parser.cpp new file mode 100644 index 00000000..557cb2c6 --- /dev/null +++ b/src/problem/parser.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../include/loki/problem/parser.hpp" + +#include "../../include/loki/common/memory.hpp" +#include "../../include/loki/common/ast/error_reporting.hpp" +#include "../../include/loki/common/pddl/error_reporting.hpp" +#include "../../include/loki/common/pddl/context.hpp" +#include "../../include/loki/common/filesystem.hpp" +#include "../../include/loki/common/ast/parser_wrapper.hpp" +#include "../../include/loki/common/exceptions.hpp" +#include "../../include/loki/problem/ast/parser.hpp" +#include "../../include/loki/problem/ast/ast.hpp" +#include "../../include/loki/problem/pddl/parser.hpp" + +#include +#include + + +namespace loki { + +ProblemParser::ProblemParser(const fs::path& file_path, DomainParser& domain_parser) + : m_file_path(file_path) + , m_source(loki::read_file(file_path)) + , m_position_cache(nullptr) + , m_scopes(nullptr) { + const auto start = std::chrono::high_resolution_clock::now(); + std::cout << "Started parsing problem file: " << file_path << std::endl; + + /* Parse the AST */ + auto problem_node = problem::ast::Problem(); + auto x3_error_handler = X3ErrorHandler(m_source.begin(), m_source.end(), file_path); + bool success = parse_ast(m_source, problem::problem(), problem_node, x3_error_handler.get_error_handler()); + if (!success) { + throw SyntaxParserError("", x3_error_handler.get_error_stream().str()); + } + + /* Parse the problem to PDDL */ + // Initialize the context + auto composite_factories = CompositeOfPDDLFactories{ + domain_parser.m_factories.requirements, + domain_parser.m_factories.types, + domain_parser.m_factories.variables, + domain_parser.m_factories.terms, + domain_parser.m_factories.objects, // use factory shared between domain and problem to include constants in indexing 0,1,... + domain_parser.m_factories.problem_atoms, // use problem specific factory to obtain indexing 0,1,... + domain_parser.m_factories.problem_literals, // use problem specific factory to obtain indexing 0,1,... + domain_parser.m_factories.parameters, + domain_parser.m_factories.predicates, + domain_parser.m_factories.function_expressions, + domain_parser.m_factories.functions, + domain_parser.m_factories.function_skeletons, + domain_parser.m_factories.conditions, + domain_parser.m_factories.effects, + domain_parser.m_factories.actions, + domain_parser.m_factories.derived_predicates, + domain_parser.m_factories.optimization_metrics, + domain_parser.m_factories.numeric_fluents, + domain_parser.m_factories.domains, + domain_parser.m_factories.problems + }; + m_position_cache = std::make_unique(x3_error_handler, file_path); + m_scopes = std::make_unique(m_position_cache->get_error_handler(), domain_parser.m_scopes.get()); + + auto context = Context(composite_factories, *m_position_cache, *m_scopes); + + // Initialize global scope + context.scopes.open_scope(); + + m_problem = parse(problem_node, context, domain_parser.get_domain()); + + // Only the global scope remains + assert(context.scopes.get_stack().size() == 1); + + const auto [vm_usage, resident_set] = process_mem_usage(); + const auto stop = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(stop - start); + std::cout << "Finished parsing after " << duration.count() << " milliseconds." << std::endl; + std::cout << "Peak virtual memory: " << vm_usage << " KB." << std::endl; + std::cout << "Peak resident set size: " << resident_set << " KB." << std::endl; +} + +const PDDLPositionCache& ProblemParser::get_position_cache() const { + return *m_position_cache; +} + +const pddl::Problem& ProblemParser::get_problem() const { + return m_problem; +} + + +} \ No newline at end of file diff --git a/src/problem/pddl/exceptions.cpp b/src/problem/pddl/exceptions.cpp new file mode 100644 index 00000000..da036c2d --- /dev/null +++ b/src/problem/pddl/exceptions.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/problem/pddl/exceptions.hpp" + +#include "../../../include/loki/domain/pddl/domain.hpp" +#include "../../../include/loki/domain/pddl/predicate.hpp" + + +namespace loki { +/* Object */ +UnusedObjectError::UnusedObjectError(const std::string& name, const std::string& error_handler_output) + : SemanticParserError( + "The object with name \"" + name + "\" was never referred to.", error_handler_output) { } + +UndefinedObjectError::UndefinedObjectError(const std::string& name, const std::string& error_handler_output) + : SemanticParserError( + "The object with name \"" + name + "\" is undefined.", error_handler_output) { } + +MultiDefinitionObjectError::MultiDefinitionObjectError(const std::string& name, const std::string& error_handler_output) + : SemanticParserError( + "The object with name \"" + name + "\" has already been defined.", error_handler_output) { } + +/* Compatibility errors */ +MismatchedDomainError::MismatchedDomainError( + const pddl::Domain& domain, + const std::string& domain_name, + const std::string& error_handler_output) + : SemanticParserError( + "Mismatched domain names \"" + + domain->get_name() + + "!=" + + domain_name + + ".", + error_handler_output) { } + +MismatchedPredicateObjectListError::MismatchedPredicateObjectListError( + const pddl::Predicate& predicate, + const pddl::ObjectList& object_list, + const std::string& error_handler_output) + : SemanticParserError( + "Mismatched number of terms for predicate \"" + + predicate->get_name() + + "\" with sizes " + + std::to_string(predicate->get_parameters().size()) + + "!=" + + std::to_string(object_list.size()) + + ".", + error_handler_output) { } + + +NegativeCostError::NegativeCostError( + const std::string& error_handler_output) + : SemanticParserError( + "Negative numbers in initial numeric fluents are not allowed with :action-costs", + error_handler_output) { } + +} \ No newline at end of file diff --git a/src/problem/pddl/metric.cpp b/src/problem/pddl/metric.cpp new file mode 100644 index 00000000..c5479a55 --- /dev/null +++ b/src/problem/pddl/metric.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/problem/pddl/metric.hpp" + +#include "../../../include/loki/common/hash.hpp" +#include "../../../include/loki/common/collections.hpp" +#include "../../../include/loki/domain/pddl/function_expressions.hpp" +#include "../../../include/loki/common/pddl/visitors.hpp" + +#include + +using namespace std; + + +namespace loki::pddl { +std::unordered_map optimization_metric_enum_to_string = { + { OptimizationMetricEnum::MINIMIZE, "minimize" }, + { OptimizationMetricEnum::MAXIMIZE, "maximize" }, +}; + +const std::string& to_string(pddl::OptimizationMetricEnum optimization_metric) { + assert(optimization_metric_enum_to_string.count(optimization_metric)); + return optimization_metric_enum_to_string.at(optimization_metric); +} + + +OptimizationMetricImpl::OptimizationMetricImpl(int identifier, OptimizationMetricEnum optimization_metric, FunctionExpression function_expression) + : Base(identifier) + , m_optimization_metric(optimization_metric) + , m_function_expression(std::move(function_expression)) +{ +} + +bool OptimizationMetricImpl::is_structurally_equivalent_to_impl(const OptimizationMetricImpl& other) const { + return (m_optimization_metric == other.m_optimization_metric) + && (m_function_expression == other.m_function_expression); +} + +size_t OptimizationMetricImpl::hash_impl() const { + return hash_combine( + m_optimization_metric, + m_function_expression); +} + +void OptimizationMetricImpl::str_impl(std::ostringstream& out, const FormattingOptions& options) const { + out << "(" << to_string(m_optimization_metric) << " "; + std::visit(StringifyVisitor(out, options), *m_function_expression); + out << ")"; +} + + +OptimizationMetricEnum OptimizationMetricImpl::get_optimization_metric() const { + return m_optimization_metric; +} + +const FunctionExpression& OptimizationMetricImpl::get_function_expression() const { + return m_function_expression; +} + +} + + +namespace std { + bool less::operator()( + const loki::pddl::OptimizationMetric& left_metric, + const loki::pddl::OptimizationMetric& right_metric) const { + return *left_metric < *right_metric; + } + + std::size_t hash::operator()(const loki::pddl::OptimizationMetricImpl& metric) const { + return metric.hash_impl(); + } +} diff --git a/src/problem/pddl/numeric_fluent.cpp b/src/problem/pddl/numeric_fluent.cpp new file mode 100644 index 00000000..216f48f8 --- /dev/null +++ b/src/problem/pddl/numeric_fluent.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/problem/pddl/numeric_fluent.hpp" + +#include "../../../include/loki/common/hash.hpp" +#include "../../../include/loki/domain/pddl/function.hpp" + + +namespace loki::pddl { +NumericFluentImpl::NumericFluentImpl(int identifier, Function function, double number) + : Base(identifier), m_function(std::move(function)), m_number(number) { } + +bool NumericFluentImpl::is_structurally_equivalent_to_impl(const NumericFluentImpl& other) const { + return (m_function == other.m_function) + && (m_number == other.m_number); +} + +size_t NumericFluentImpl::hash_impl() const { + return hash_combine(m_function, m_number); +} + +void NumericFluentImpl::str_impl(std::ostringstream& out, const FormattingOptions& /*options*/) const { + out << "(= " << *m_function << " " << m_number << ")"; +} + +const Function& NumericFluentImpl::get_function() const { + return m_function; +} + +double NumericFluentImpl::get_number() const { + return m_number; +} + +} + + + +namespace std { + bool less::operator()( + const loki::pddl::NumericFluent& left_numeric_fluent, + const loki::pddl::NumericFluent& right_numeric_fluent) const { + return *left_numeric_fluent < *right_numeric_fluent; + } + + std::size_t hash::operator()(const loki::pddl::NumericFluentImpl& numeric_fluent) const { + return numeric_fluent.hash_impl(); + } +} diff --git a/src/problem/pddl/parser.cpp b/src/problem/pddl/parser.cpp new file mode 100644 index 00000000..b5c5051e --- /dev/null +++ b/src/problem/pddl/parser.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/problem/pddl/parser.hpp" + +#include "parser/objects.hpp" +#include "parser/initial.hpp" +#include "parser/goal.hpp" +#include "parser/metric.hpp" + +#include "../../domain/pddl/parser/common.hpp" +#include "../../domain/pddl/parser/requirements.hpp" +#include "../../domain/pddl/unpacking_visitor.hpp" + +#include "../../../include/loki/problem/pddl/exceptions.hpp" +#include "../../../include/loki/domain/pddl/domain.hpp" +#include "../../../include/loki/domain/pddl/requirements.hpp" + + +namespace loki { + +pddl::Problem parse(const problem::ast::Problem& problem_node, Context& context, const pddl::Domain& domain) { + /* Domain name section */ + const auto domain_name = parse(problem_node.domain_name.name); + if (domain_name != domain->get_name()) { + throw MismatchedDomainError(domain, domain_name, context.scopes.get_error_handler()(problem_node.domain_name, "")); + } + /* Problem name section */ + const auto problem_name = parse(problem_node.problem_name.name); + /* Requirements section */ + if (problem_node.requirements.has_value()) { + context.requirements = context.factories.requirements.get_or_create( + parse(problem_node.requirements.value(), context)); + context.positions.push_back(context.requirements, problem_node.requirements.value()); + } else { + // Default requirements + context.requirements = context.factories.requirements.get_or_create( + pddl::RequirementEnumSet{pddl::RequirementEnum::STRIPS}); + } + /* Objects section */ + auto objects = pddl::ObjectList(); + if (problem_node.objects.has_value()) { + objects = parse(problem_node.objects.value(), context); + } + for (const auto& object : objects) { + context.references.track(object); + } + /* Initial section */ + auto initial_literals = pddl::LiteralList(); + auto numeric_fluents = pddl::NumericFluentList(); + const auto initial_elements = parse(problem_node.initial, context); + for (const auto& initial_element : initial_elements) { + std::visit(UnpackingVisitor(initial_literals, numeric_fluents), initial_element); + } + /* Goal section */ + const auto goal_condition = parse(problem_node.goal, context); + /* Metric section */ + auto optimization_metric = std::optional(); + if (problem_node.metric_specification.has_value()) { + optimization_metric = parse(problem_node.metric_specification.value(), context); + } + + // Check references + for (const auto& object : objects) { + if (context.references.exists(object)) { + const auto& [_object, position, error_handler] = context.scopes.get(object->get_name()).value(); + throw UnusedObjectError(object->get_name(), error_handler(position.value(), "")); + } + } + + const auto problem = context.factories.problems.get_or_create(domain, problem_name, context.requirements, objects, initial_literals, numeric_fluents, goal_condition, optimization_metric); + context.positions.push_back(problem, problem_node); + return problem; +} + +} \ No newline at end of file diff --git a/src/problem/pddl/parser/function.cpp b/src/problem/pddl/parser/function.cpp new file mode 100644 index 00000000..0529be50 --- /dev/null +++ b/src/problem/pddl/parser/function.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "function.hpp" + +#include "objects.hpp" + +#include "../../../domain/pddl/parser/common.hpp" +#include "../../../domain/pddl/parser/functions.hpp" +#include "../../../../include/loki/domain/pddl/exceptions.hpp" + + +namespace loki { + +/* FunctionExpression */ +pddl::FunctionExpression parse(const problem::ast::MetricFunctionExpressionNumber& node, Context& context) { + const auto number = parse(node.number); + const auto function_expression = context.factories.function_expressions.get_or_create(number); + context.positions.push_back(function_expression, node); + return function_expression; +} + +pddl::FunctionExpression parse(const problem::ast::MetricFunctionExpressionBinaryOperator& node, Context& context) { + const auto binary_operator = boost::apply_visitor(BinaryOperatorVisitor(), node.binary_operator); + const auto left_function_expression = parse(node.metric_function_expression_left, context); + const auto right_function_expression = parse(node.metric_function_expression_right, context); + const auto function_expression = context.factories.function_expressions.get_or_create(binary_operator, left_function_expression, right_function_expression); + context.positions.push_back(function_expression, node); + return function_expression; +} + +pddl::FunctionExpression parse(const problem::ast::MetricFunctionExpressionMultiOperator& node, Context& context) { + const auto multi_operator = boost::apply_visitor(MultiOperatorVisitor(), node.multi_operator); + auto function_expressions = pddl::FunctionExpressionList(); + const auto first_function_expression = parse(node.metric_function_expression_first, context); + function_expressions.push_back(first_function_expression); + for (const auto& child_node : node.metric_function_expression_remaining) { + const auto next_function_expression = parse(child_node, context); + function_expressions.push_back(next_function_expression); + } + const auto function_expression = context.factories.function_expressions.get_or_create(multi_operator, function_expressions); + context.positions.push_back(function_expression, node); + return function_expression; +} + +pddl::FunctionExpression parse(const problem::ast::MetricFunctionExpressionMinus& node, Context& context) { + const auto child_function_expression = parse(node.metric_function_expression, context); + const auto function_expression = context.factories.function_expressions.get_or_create(child_function_expression); + context.positions.push_back(function_expression, node); + return function_expression; +} + +pddl::FunctionExpression parse(const problem::ast::MetricFunctionExpressionBasicFunctionTerm& node, Context& context) { + const auto function = parse(node.basic_function_term, context); + const auto function_expression = context.factories.function_expressions.get_or_create(function); + context.positions.push_back(function_expression, node); + return function_expression; +} + +pddl::FunctionExpression parse(const problem::ast::MetricFunctionExpressionTotalTime& /*node*/, Context& /*context*/) { + throw NotImplementedError("parse(const problem::ast::MetricFunctionExpressionTotalTime& node, Context& context)"); +} + +pddl::FunctionExpression parse(const problem::ast::MetricFunctionExpressionPreferences& /*node*/, Context& /*context*/) { + throw NotImplementedError("parse(const problem::ast::MetricFunctionExpressionPreferences& node, Context& context)"); +} + +pddl::FunctionExpression parse(const problem::ast::MetricFunctionExpression& node, Context& context) { + return boost::apply_visitor(MetricFunctionExpressionDeclarationVisitor(context), node); +} + +MetricFunctionExpressionDeclarationVisitor::MetricFunctionExpressionDeclarationVisitor(Context& context_) : context(context_) { } + + +/* Function */ +pddl::Function parse(const problem::ast::BasicFunctionTerm& node, Context& context) { + const auto function_skeleton = parse_function_skeleton_reference(node.function_symbol, context); + auto term_list = pddl::TermList(); + for (const auto& name_node : node.names) { + term_list.push_back(context.factories.terms.get_or_create(parse_object_reference(name_node, context))); + } + if (function_skeleton->get_parameters().size() != term_list.size()) { + throw MismatchedFunctionSkeletonTermListError(function_skeleton, term_list, context.scopes.get_error_handler()(node, "")); + } + const auto function = context.factories.functions.get_or_create(function_skeleton, term_list); + context.positions.push_back(function, node); + return function; +} + +} diff --git a/src/problem/pddl/parser/function.hpp b/src/problem/pddl/parser/function.hpp new file mode 100644 index 00000000..cd770c8b --- /dev/null +++ b/src/problem/pddl/parser/function.hpp @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_PROBLEM_PDDL_PARSER_FUNCTION_HPP_ +#define LOKI_SRC_PROBLEM_PDDL_PARSER_FUNCTION_HPP_ + +#include "../../../../include/loki/problem/ast/ast.hpp" +#include "../../../../include/loki/problem/pddl/parser.hpp" + + + +namespace loki { + +/* FunctionExpression */ +extern pddl::FunctionExpression parse(const problem::ast::MetricFunctionExpression& node, Context& context); +extern pddl::FunctionExpression parse(const problem::ast::MetricFunctionExpressionNumber& node, Context& context); +extern pddl::FunctionExpression parse(const problem::ast::MetricFunctionExpressionBinaryOperator& node, Context& context); +extern pddl::FunctionExpression parse(const problem::ast::MetricFunctionExpressionMultiOperator& node, Context& context); +extern pddl::FunctionExpression parse(const problem::ast::MetricFunctionExpressionMinus& node, Context& context); +extern pddl::FunctionExpression parse(const problem::ast::MetricFunctionExpressionBasicFunctionTerm& node, Context& context); +extern pddl::FunctionExpression parse(const problem::ast::MetricFunctionExpressionTotalTime& node, Context& context); +extern pddl::FunctionExpression parse(const problem::ast::MetricFunctionExpressionPreferences& node, Context& context); + +class MetricFunctionExpressionDeclarationVisitor : boost::static_visitor { +private: + Context& context; + +public: + MetricFunctionExpressionDeclarationVisitor(Context& context_); + + template + pddl::FunctionExpression operator()(const Node& node) const { + return parse(node, context); + } +}; + + +/* Function */ +extern pddl::Function parse(const problem::ast::BasicFunctionTerm& node, Context& context); + +} + +#endif diff --git a/src/problem/pddl/parser/goal.cpp b/src/problem/pddl/parser/goal.cpp new file mode 100644 index 00000000..9c9139a6 --- /dev/null +++ b/src/problem/pddl/parser/goal.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "goal.hpp" + +#include "../../../domain/pddl/parser/conditions.hpp" + + +namespace loki { + +pddl::Condition parse(const problem::ast::Goal& node, Context& context) { + return parse(node.precondition_goal_descriptor, context); +} + +} diff --git a/src/problem/pddl/parser/goal.hpp b/src/problem/pddl/parser/goal.hpp new file mode 100644 index 00000000..e058fb9d --- /dev/null +++ b/src/problem/pddl/parser/goal.hpp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_PROBLEM_PDDL_PARSER_GOAL_HPP_ +#define LOKI_SRC_PROBLEM_PDDL_PARSER_GOAL_HPP_ + +#include "../../../../include/loki/problem/ast/ast.hpp" +#include "../../../../include/loki/problem/pddl/parser.hpp" + + + +namespace loki { + +extern pddl::Condition parse(const problem::ast::Goal& node, Context& context); + +} + +#endif diff --git a/src/problem/pddl/parser/initial.cpp b/src/problem/pddl/parser/initial.cpp new file mode 100644 index 00000000..19dbc29d --- /dev/null +++ b/src/problem/pddl/parser/initial.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "initial.hpp" + +#include "literal.hpp" +#include "function.hpp" + +#include "../../../../include/loki/common/exceptions.hpp" +#include "../../../../include/loki/domain/pddl/exceptions.hpp" +#include "../../../../include/loki/problem/pddl/exceptions.hpp" +#include "../../../domain/pddl/parser/common.hpp" +#include "../../../domain/pddl/parser/functions.hpp" + + +namespace loki { + +std::vector> parse( + const problem::ast::Initial& initial_node, Context& context) { + auto initial_element_list = std::vector>(); + for (const auto& initial_element : initial_node.initial_elements) { + initial_element_list.push_back(boost::apply_visitor(InitialElementVisitor(context), initial_element)); + } + return initial_element_list; +} + +std::variant parse(const problem::ast::InitialElementLiteral& node, Context& context) { + return parse(node.literal, context); +} + +std::variant parse(const problem::ast::InitialElementTimedLiterals& /*node*/, Context& /*context*/) { + throw NotImplementedError("InitialElementVisitor::operator()(const problem::ast::InitialElementTimedLiterals& node)"); +} + +std::variant parse(const problem::ast::InitialElementNumericFluentsTotalCost& node, Context& context) { + if (!context.requirements->test(pddl::RequirementEnum::ACTION_COSTS)) { + throw UndefinedRequirementError(pddl::RequirementEnum::ACTION_COSTS, context.scopes.get_error_handler()(node, "")); + } + context.references.untrack(pddl::RequirementEnum::ACTION_COSTS); + const auto function_skeleton = parse_function_skeleton_reference(node.function_symbol_total_cost, context); + const auto basic_function_term = context.factories.functions.get_or_create(function_skeleton, pddl::TermList{}); + double number = parse(node.number); + if (number < 0) { + throw NegativeCostError(context.positions.get_error_handler()(node.number, "")); + } + return context.factories.numeric_fluents.get_or_create(basic_function_term, number); +} + +std::variant parse(const problem::ast::InitialElementNumericFluentsGeneral& node, Context& context) { + if (!context.requirements->test(pddl::RequirementEnum::NUMERIC_FLUENTS)) { + throw UndefinedRequirementError(pddl::RequirementEnum::NUMERIC_FLUENTS, context.scopes.get_error_handler()(node, "")); + } + context.references.untrack(pddl::RequirementEnum::NUMERIC_FLUENTS); + const auto basic_function_term = parse(node.basic_function_term, context); + double number = parse(node.number); + if (number < 0 && context.requirements->test(pddl::RequirementEnum::ACTION_COSTS)) { + throw NegativeCostError(context.positions.get_error_handler()(node.number, "")); + } + return context.factories.numeric_fluents.get_or_create(basic_function_term, number); +} + +InitialElementVisitor::InitialElementVisitor(Context& context_) + : context(context_) { } + +} diff --git a/src/problem/pddl/parser/initial.hpp b/src/problem/pddl/parser/initial.hpp new file mode 100644 index 00000000..c6a8f47f --- /dev/null +++ b/src/problem/pddl/parser/initial.hpp @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_PROBLEM_PDDL_PARSER_INITIAL_HPP_ +#define LOKI_SRC_PROBLEM_PDDL_PARSER_INITIAL_HPP_ + +#include "../../../../include/loki/problem/ast/ast.hpp" +#include "../../../../include/loki/problem/pddl/parser.hpp" + +#include + + +namespace loki { + +/* Init */ +extern std::vector> parse( + const problem::ast::Initial& initial_node, Context& context); + +extern std::variant parse( + const problem::ast::InitialElementLiteral& node); +extern std::variant parse( + const problem::ast::InitialElementTimedLiterals& node); +extern std::variant parse( + const problem::ast::InitialElementNumericFluentsTotalCost& node); +extern std::variant parse( + const problem::ast::InitialElementNumericFluentsGeneral& node); + +class InitialElementVisitor : boost::static_visitor> { +private: + Context& context; + +public: + InitialElementVisitor(Context& context_); + + template + std::variant operator()(const Node& node) const { + return parse(node, context); + } +}; + +} + +#endif diff --git a/src/problem/pddl/parser/literal.cpp b/src/problem/pddl/parser/literal.cpp new file mode 100644 index 00000000..e793a877 --- /dev/null +++ b/src/problem/pddl/parser/literal.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "literal.hpp" + +#include "objects.hpp" + +#include "../../../../include/loki/domain/pddl/exceptions.hpp" +#include "../../../../include/loki/problem/pddl/exceptions.hpp" +#include "../../../domain/pddl/parser/common.hpp" + + +namespace loki { + +AtomicFormulaOfNamesVisitor::AtomicFormulaOfNamesVisitor(Context& context_) : context(context_) { } + +pddl::Atom parse(const problem::ast::AtomicFormulaOfNamesPredicate& node, Context& context) { + const auto name = parse(node.predicate.name); + const auto binding = context.scopes.get(name); + if (!binding.has_value()) { + throw UndefinedPredicateError(name, context.scopes.get_error_handler()(node, "")); + } + auto term_list = pddl::TermList(); + for (const auto& name_node : node.names) { + term_list.push_back(context.factories.terms.get_or_create(parse_object_reference(name_node, context))); + } + const auto& [predicate, _position, _error_handler] = binding.value(); + if (predicate->get_parameters().size() != term_list.size()) { + throw MismatchedPredicateTermListError(predicate, term_list, context.scopes.get_error_handler()(node, "")); + } + const auto atom = context.factories.atoms.get_or_create(predicate, term_list); + context.positions.push_back(atom, node); + return atom; +} + +pddl::Atom parse(const problem::ast::AtomicFormulaOfNamesEquality& node, Context& context) { + if (!context.requirements->test(pddl::RequirementEnum::EQUALITY)) { + throw UndefinedRequirementError(pddl::RequirementEnum::EQUALITY, context.scopes.get_error_handler()(node, "")); + } + assert(context.scopes.get("=").has_value()); + const auto& [equal_predicate, _position, _error_handler] = context.scopes.get("=").value(); + const auto term_left = context.factories.terms.get_or_create(parse_object_reference(node.name_left, context)); + const auto term_right = context.factories.terms.get_or_create(parse_object_reference(node.name_right, context)); + const auto atom = context.factories.atoms.get_or_create(equal_predicate, pddl::TermList{term_left, term_right}); + context.positions.push_back(atom, node); + return atom; +} + +pddl::Atom parse(const problem::ast::AtomicFormulaOfNames& node, Context& context) { + return boost::apply_visitor(AtomicFormulaOfNamesVisitor(context), node); +} + + +GroundLiteralVisitor::GroundLiteralVisitor(Context& context_) : context(context_) { } + + +pddl::Literal parse(const problem::ast::Atom& node, Context& context) { + const auto literal = context.factories.literals.get_or_create(false, parse(node.atomic_formula_of_names, context)); + context.positions.push_back(literal, node); + return literal; +} + +pddl::Literal parse(const problem::ast::NegatedAtom& node, Context& context) { + const auto literal = context.factories.literals.get_or_create(true, parse(node.atomic_formula_of_names, context)); + context.positions.push_back(literal, node); + return literal; +} + +pddl::Literal parse(const problem::ast::Literal& node, Context& context) { + return boost::apply_visitor(GroundLiteralVisitor(context), node); +} + +} \ No newline at end of file diff --git a/src/problem/pddl/parser/literal.hpp b/src/problem/pddl/parser/literal.hpp new file mode 100644 index 00000000..09bf3f33 --- /dev/null +++ b/src/problem/pddl/parser/literal.hpp @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_PROBLEM_PDDL_PARSER_GROUND_LITERAL_HPP_ +#define LOKI_SRC_PROBLEM_PDDL_PARSER_GROUND_LITERAL_HPP_ + +#include "../../../../include/loki/problem/ast/ast.hpp" +#include "../../../../include/loki/problem/pddl/parser.hpp" + + +namespace loki { + +/* Atom */ +extern pddl::Atom parse(const problem::ast::AtomicFormulaOfNamesPredicate& node, Context& context); +extern pddl::Atom parse(const problem::ast::AtomicFormulaOfNamesEquality& node, Context& context); +extern pddl::Atom parse(const problem::ast::AtomicFormulaOfNames& node, Context& context); + +class AtomicFormulaOfNamesVisitor : boost::static_visitor { +private: + Context& context; + +public: + AtomicFormulaOfNamesVisitor(Context& context_); + + template + pddl::Atom operator()(const Node& node) const { + return parse(node, context); + } +}; + + +/* Literal */ +extern pddl::Literal parse(const problem::ast::Atom& node, Context& context); +extern pddl::Literal parse(const problem::ast::NegatedAtom& node, Context& context); +extern pddl::Literal parse(const problem::ast::Literal& node, Context& context); + +class GroundLiteralVisitor : boost::static_visitor { +private: + Context& context; + +public: + GroundLiteralVisitor(Context& context_); + + template + pddl::Literal operator()(const Node& node) const { + return parse(node, context); + } +}; + +} + +#endif // LOKI_SRC_DOMAIN_PDDL_PARSER_OBJECTS_HPP_ diff --git a/src/problem/pddl/parser/metric.cpp b/src/problem/pddl/parser/metric.cpp new file mode 100644 index 00000000..b8f039fb --- /dev/null +++ b/src/problem/pddl/parser/metric.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "metric.hpp" + +#include "function.hpp" + +#include "../../../domain/pddl/parser/common.hpp" +#include "../../../domain/pddl/parser/functions.hpp" +#include "../../../../include/loki/problem/pddl/exceptions.hpp" +#include "../../../../include/loki/domain/pddl/exceptions.hpp" + + +using namespace loki::problem; +using namespace std; + + +namespace loki { + +/* OptimizationMetricEnum */ +pddl::OptimizationMetricEnum parse(const problem::ast::Optimization& node, Context& context) { + return boost::apply_visitor(OptimizationDeclarationVisitor(context), node); +} + +pddl::OptimizationMetricEnum parse(const problem::ast::OptimizationMinimize& /*node*/, Context& /*context*/) { + return pddl::OptimizationMetricEnum::MINIMIZE; +} + +pddl::OptimizationMetricEnum parse(const problem::ast::OptimizationMaximize& /*node*/, Context& /*context*/) { + return pddl::OptimizationMetricEnum::MAXIMIZE; +} + +OptimizationDeclarationVisitor::OptimizationDeclarationVisitor(Context& context_) : context(context_) { } + + +/* OptimizationMetric */ +pddl::OptimizationMetric parse(const problem::ast::MetricSpecification& node, Context& context) { + return boost::apply_visitor(MetricSpecificationDeclarationVisitor(context), node); +} + +pddl::OptimizationMetric parse(const problem::ast::MetricSpecificationTotalCost& node, Context& context) { + const auto optimization = pddl::OptimizationMetricEnum::MINIMIZE; + const auto function_skeleton = parse_function_skeleton_reference(node.function_symbol_total_cost, context); + const auto function = context.factories.functions.get_or_create(function_skeleton, pddl::TermList{}); + const auto function_expression = context.factories.function_expressions.get_or_create(function); + return context.factories.optimization_metrics.get_or_create(optimization, function_expression); +} + +pddl::OptimizationMetric parse(const problem::ast::MetricSpecificationGeneral& node, Context& context) { + const auto optimization = parse(node.optimization, context); + const auto function_expression = parse(node.metric_function_expression, context); + return context.factories.optimization_metrics.get_or_create(optimization, function_expression); +} + +MetricSpecificationDeclarationVisitor::MetricSpecificationDeclarationVisitor(Context& context_) : context(context_) { } + +} diff --git a/src/problem/pddl/parser/metric.hpp b/src/problem/pddl/parser/metric.hpp new file mode 100644 index 00000000..7c1b63f5 --- /dev/null +++ b/src/problem/pddl/parser/metric.hpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_PROBLEM_PDDL_PARSER_METRIC_HPP_ +#define LOKI_SRC_PROBLEM_PDDL_PARSER_METRIC_HPP_ + +#include "../../../../include/loki/problem/ast/ast.hpp" +#include "../../../../include/loki/problem/pddl/parser.hpp" + + + +namespace loki { + +/* OptimizationMetricEnum */ +extern pddl::OptimizationMetricEnum parse(const problem::ast::Optimization& node, Context& context); +extern pddl::OptimizationMetricEnum parse(const problem::ast::OptimizationMinimize& node, Context& context); +extern pddl::OptimizationMetricEnum parse(const problem::ast::OptimizationMaximize& node, Context& context); + +class OptimizationDeclarationVisitor : boost::static_visitor { +private: + Context& context; + +public: + OptimizationDeclarationVisitor(Context& context_); + + template + pddl::OptimizationMetricEnum operator()(const Node& node) const { + return parse(node, context); + } +}; + + +/* OptimizationMetric */ +extern pddl::OptimizationMetric parse(const problem::ast::MetricSpecification& node, Context& context); +extern pddl::OptimizationMetric parse(const problem::ast::MetricSpecificationTotalCost& node, Context& context); +extern pddl::OptimizationMetric parse(const problem::ast::MetricSpecificationGeneral& node, Context& context); + +class MetricSpecificationDeclarationVisitor : boost::static_visitor { +private: + Context& context; + +public: + MetricSpecificationDeclarationVisitor(Context& context_); + + template + pddl::OptimizationMetric operator()(const Node& node) const { + return parse(node, context); + } +}; + +} + +#endif diff --git a/src/problem/pddl/parser/objects.cpp b/src/problem/pddl/parser/objects.cpp new file mode 100644 index 00000000..c3d9f87f --- /dev/null +++ b/src/problem/pddl/parser/objects.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "objects.hpp" + +#include "../../../domain/pddl/parser/common.hpp" +#include "../../../domain/pddl/parser/types.hpp" +#include "../../../../include/loki/problem/pddl/exceptions.hpp" +#include "../../../../include/loki/domain/pddl/exceptions.hpp" + + +using namespace loki::problem; +using namespace std; + + +namespace loki { + +ObjectListVisitor::ObjectListVisitor(Context& context_) + : context(context_) { } + + +pddl::Object parse_object_reference(const domain::ast::Name& name_node, Context& context) { + const auto name = parse(name_node); + const auto binding = context.scopes.get(name); + if (!binding.has_value()) { + throw UndefinedObjectError(name, context.scopes.get_error_handler()(name_node, "")); + } + const auto& [object, _position, _error_handler] = binding.value(); + context.positions.push_back(object, name_node); + context.references.untrack(object); + return object; +} + + +static void test_multiple_definition_object(const std::string& object_name, const domain::ast::Name& name_node, const Context& context) { + const auto binding = context.scopes.get(object_name); + if (binding.has_value()) { + const auto message_1 = context.scopes.get_error_handler()(name_node, "Defined here:"); + auto message_2 = std::string(""); + const auto& [_object, position, error_handler] = binding.value(); + if (position.has_value()) { + message_2 = error_handler(position.value(), "First defined here:"); + } + throw MultiDefinitionObjectError(object_name, message_1 + message_2); + } +} + + +static pddl::Object parse_object_definition(const domain::ast::Name& name_node, const pddl::TypeList& type_list, Context& context) { + const auto name = parse(name_node); + test_multiple_definition_object(name, name_node, context); + const auto object = context.factories.objects.get_or_create(name, type_list); + context.positions.push_back(object, name_node); + context.scopes.insert(name, object, name_node); + return object; +} + + +static pddl::ObjectList parse_object_definitions(const std::vector& name_nodes, const pddl::TypeList& type_list, Context& context) { + auto object_list = pddl::ObjectList(); + for (const auto& name_node : name_nodes) { + object_list.emplace_back(parse_object_definition(name_node, type_list, context)); + } + return object_list; +} + + +pddl::ObjectList ObjectListVisitor::operator()(const std::vector& name_nodes) { + // std::vector has single base type "object" + assert(context.scopes.get("object").has_value()); + const auto& [type, _position, _error_handler] = context.scopes.get("object").value(); + auto object_list = parse_object_definitions(name_nodes, pddl::TypeList{type}, context); + return object_list; +} + +pddl::ObjectList ObjectListVisitor::operator()(const domain::ast::TypedListOfNamesRecursively& node) { + if (!context.requirements->test(pddl::RequirementEnum::TYPING)) { + throw UndefinedRequirementError(pddl::RequirementEnum::TYPING, context.scopes.get_error_handler()(node, "")); + } + context.references.untrack(pddl::RequirementEnum::TYPING); + // TypedListOfNamesRecursively has user defined base types + const auto type_list = boost::apply_visitor(TypeReferenceTypeVisitor(context), node.type); + auto object_list = parse_object_definitions(node.names, type_list, context); + // Recursively add objects. + auto additional_objects = boost::apply_visitor(*this, node.typed_list_of_names.get()); + object_list.insert(object_list.end(), additional_objects.begin(), additional_objects.end()); + return object_list; +} + +pddl::ObjectList parse(const ast::Objects& objects_node, Context& context) { + return boost::apply_visitor(ObjectListVisitor(context), objects_node.typed_list_of_names); +} + +} diff --git a/src/problem/pddl/parser/objects.hpp b/src/problem/pddl/parser/objects.hpp new file mode 100644 index 00000000..45c0d679 --- /dev/null +++ b/src/problem/pddl/parser/objects.hpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOKI_SRC_PROBLEM_PDDL_PARSER_OBJECTS_HPP_ +#define LOKI_SRC_PROBLEM_PDDL_PARSER_OBJECTS_HPP_ + +#include "../../../../include/loki/problem/ast/ast.hpp" +#include "../../../../include/loki/problem/pddl/parser.hpp" + + +namespace loki { + +/* Object */ +extern pddl::Object parse_object_reference(const domain::ast::Name& name_node, Context& context); + +extern pddl::ObjectList parse(const problem::ast::Objects& objects_node, Context& context); + +class ObjectListVisitor : boost::static_visitor { +private: + Context& context; + +public: + ObjectListVisitor(Context& context_); + + pddl::ObjectList operator()(const std::vector& name_nodes); + + pddl::ObjectList operator()(const domain::ast::TypedListOfNamesRecursively& typed_list_of_names_recursively_node); +}; + +} + +#endif // LOKI_SRC_DOMAIN_PDDL_PARSER_OBJECTS_HPP_ diff --git a/src/problem/pddl/problem.cpp b/src/problem/pddl/problem.cpp new file mode 100644 index 00000000..1eb2d5d9 --- /dev/null +++ b/src/problem/pddl/problem.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/problem/pddl/problem.hpp" + +#include "../../../include/loki/problem/pddl/metric.hpp" +#include "../../../include/loki/problem/pddl/numeric_fluent.hpp" +#include "../../../include/loki/common/hash.hpp" +#include "../../../include/loki/common/collections.hpp" +#include "../../../include/loki/domain/pddl/conditions.hpp" +#include "../../../include/loki/domain/pddl/literal.hpp" +#include "../../../include/loki/domain/pddl/domain.hpp" +#include "../../../include/loki/domain/pddl/requirements.hpp" +#include "../../../include/loki/domain/pddl/object.hpp" +#include "../../../include/loki/common/pddl/visitors.hpp" + +using namespace std; + + +namespace loki::pddl { +ProblemImpl::ProblemImpl(int identifier, Domain domain, std::string name, Requirements requirements, ObjectList objects, LiteralList initial_literals, NumericFluentList numeric_fluents, Condition goal_condition, std::optional optimization_metric) + : Base(identifier) + , m_domain(std::move(domain)) + , m_name(std::move(name)) + , m_requirements(std::move(requirements)) + , m_objects(std::move(objects)) + , m_initial_literals(std::move(initial_literals)) + , m_numeric_fluents(std::move(numeric_fluents)) + , m_goal_condition(std::move(goal_condition)) + , m_optimization_metric(std::move(optimization_metric)) +{ +} + +bool ProblemImpl::is_structurally_equivalent_to_impl(const ProblemImpl& other) const { + return (m_domain == other.m_domain) + && (m_name == other.m_name) + && (m_requirements == other.m_requirements) + && (get_sorted_vector(m_objects) == get_sorted_vector(other.m_objects)) + && (get_sorted_vector(m_initial_literals)) == get_sorted_vector(other.m_initial_literals) + && (m_goal_condition == other.m_goal_condition) + && (m_optimization_metric == other.m_optimization_metric); +} + +size_t ProblemImpl::hash_impl() const { + size_t optimization_hash = (m_optimization_metric.has_value()) ? hash_combine(m_optimization_metric) : 0; + return hash_combine( + m_domain, + m_name, + m_requirements, + hash_container(get_sorted_vector(m_objects)), + hash_container(get_sorted_vector(m_initial_literals)), + m_goal_condition, + optimization_hash); +} + +void ProblemImpl::str_impl(std::ostringstream& out, const FormattingOptions& options) const { + out << string(options.indent, ' ') << "(define (problem " << m_name << ")\n"; + auto nested_options = FormattingOptions{options.indent + options.add_indent, options.add_indent}; + out << string(nested_options.indent, ' ') << "(:domain " << m_domain->get_name() << ")\n"; + if (!m_requirements->get_requirements().empty()) { + out << string(nested_options.indent, ' ') << *m_requirements << "\n"; + } + if (!m_objects.empty()) { + out << string(nested_options.indent, ' ') << "(:objects "; + for (size_t i = 0; i < m_objects.size(); ++i) { + if (i != 0) out << " "; + out << *m_objects[i]; + } + out << ")\n"; + } + out << string(nested_options.indent, ' ') << "(:init "; + for (size_t i = 0; i < m_initial_literals.size(); ++i) { + if (i != 0) out << " "; + out << *m_initial_literals[i]; + } + out << " "; + for (size_t i = 0; i < m_numeric_fluents.size(); ++i) { + if (i != 0) out << " "; + out << *m_numeric_fluents[i]; + } + out << ")\n"; + out << string(nested_options.indent, ' ') << "(:goal "; + std::visit(StringifyVisitor(out, options), *m_goal_condition); + out << ")\n"; + if (m_optimization_metric.has_value()) { + out << string(nested_options.indent, ' ') << "(:metric " << *m_optimization_metric.value() << ")\n"; + } + /* + if (node.constraints.has_value()) { + ss << string(nested_options.indent, ' ') << parse_text(node.constraints.value(), nested_options) << "\n"; + } + */ + + out << string(options.indent, ' ') << ")"; +} + + +const Domain& ProblemImpl::get_domain() const { + return m_domain; +} + +const std::string& ProblemImpl::get_name() const { + return m_name; +} + +const Requirements& ProblemImpl::get_requirements() const { + return m_requirements; +} + +const ObjectList& ProblemImpl::get_objects() const { + return m_objects; +} + +const LiteralList& ProblemImpl::get_initial_literals() const { + return m_initial_literals; +} + +const NumericFluentList& ProblemImpl::numeric_fluents() const { + return m_numeric_fluents; +} + +const Condition& ProblemImpl::get_goal_condition() const { + return m_goal_condition; +} + +const std::optional& ProblemImpl::get_optimization_metric() const { + return m_optimization_metric; +} + +} + + +namespace std { + bool less::operator()( + const loki::pddl::Problem& left_problem, + const loki::pddl::Problem& right_problem) const { + return *left_problem < *right_problem; + } + + std::size_t hash::operator()(const loki::pddl::ProblemImpl& problem) const { + return problem.hash_impl(); + } +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 00000000..c52b0917 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,29 @@ +enable_testing() +option(INSTALL_GMOCK "Install Googletest's GMock?" OFF) +option(INSTALL_GTEST "Install Googletest's GTest?" OFF) + +set(TEST_NAME ${CMAKE_PROJECT_NAME}_tests) + +include(FetchContent) +FetchContent_Declare( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG release-1.11.0 +) +FetchContent_MakeAvailable(googletest) + +add_library(GTest::GTest INTERFACE IMPORTED) +target_link_libraries(GTest::GTest INTERFACE gtest_main) + +file(GLOB SRC_FILES + "common/pddl/*.cpp" + "domain/ast/*.cpp") + +add_executable(domain_tests ${SRC_FILES}) + +target_link_libraries(domain_tests + PRIVATE + loki::parsers + GTest::GTest) + +add_test(domain_gtests domain_tests) diff --git a/tests/common/pddl/garbage_collected_factory.cpp b/tests/common/pddl/garbage_collected_factory.cpp new file mode 100644 index 00000000..323c18a8 --- /dev/null +++ b/tests/common/pddl/garbage_collected_factory.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../../../include/loki/common/pddl/garbage_collected_factory.hpp" +#include "../../../include/loki/common/hash.hpp" +#include "../../../include/loki/domain/pddl/object.hpp" + +#include + +#include + + +namespace loki::domain::tests { + +/// @brief A type to avoid friending in the pddl::Object since this class is not used. +class ObjectImpl { +private: + int m_identifier; + std::string m_name; + + ObjectImpl(int identifier, std::string name) : m_identifier(identifier), m_name(std::move(name)) { } + + template + friend class loki::GarbageCollectedFactory; + +public: + bool operator==(const ObjectImpl& other) const { + return m_name == other.m_name; + } + + size_t hash() const { + return hash_combine(m_name); + } + + int get_identifier() const { return m_identifier; } + const std::string& get_name() const { return m_name; } +}; + +using Object = std::shared_ptr; + +} + + +namespace std { + template<> + struct hash { + size_t operator()(const loki::domain::tests::ObjectImpl& object) const { + return object.hash(); + } + }; +} + + +namespace loki::domain::tests { + +TEST(LokiTests, GarbageCollectedFactoryTest) { + GarbageCollectedFactory factory; + EXPECT_EQ(factory.size(), 0); + + { + const auto object_0_0 = factory.get_or_create("object_0"); + EXPECT_EQ(factory.size(), 1); + EXPECT_EQ(object_0_0->get_name(), "object_0"); + + const auto object_0_1 = factory.get_or_create("object_0"); + EXPECT_EQ(factory.size(), 1); + EXPECT_EQ(object_0_0, object_0_1); + + const auto object_1 = factory.get_or_create("object_1"); + EXPECT_EQ(factory.size(), 2); + + // destructors are called + } + EXPECT_EQ(factory.size(), 0); +} + +} diff --git a/tests/common/pddl/persistent_factory.cpp b/tests/common/pddl/persistent_factory.cpp new file mode 100644 index 00000000..1e170160 --- /dev/null +++ b/tests/common/pddl/persistent_factory.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "../../../include/loki/common/pddl/persistent_factory.hpp" +#include "../../../include/loki/domain/pddl/object.hpp" + + +namespace loki::domain::tests { + +TEST(LokiTests, PersistentFactoryTest) { + PersistentFactory factory; + EXPECT_EQ(factory.size(), 0); + + // Test uniqueness: insert the same element twice + const auto object_0_0 = factory.get_or_create("object_0"); + EXPECT_EQ(factory.size(), 1); + EXPECT_EQ(object_0_0->get_identifier(), 0); + EXPECT_EQ(object_0_0->get_name(), "object_0"); + + const auto object_0_1 = factory.get_or_create("object_0"); + EXPECT_EQ(factory.size(), 1); + EXPECT_EQ(object_0_0, object_0_1); + + const auto object_1 = factory.get_or_create("object_1"); + EXPECT_EQ(factory.size(), 2); + EXPECT_NE(object_0_0, object_1); + +} + +} diff --git a/tests/common/pddl/reference.cpp b/tests/common/pddl/reference.cpp new file mode 100644 index 00000000..7f193210 --- /dev/null +++ b/tests/common/pddl/reference.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "../../../include/loki/common/pddl/persistent_factory.hpp" +#include "../../../include/loki/common/pddl/reference.hpp" +#include "../../../include/loki/domain/pddl/object.hpp" + + +namespace loki::domain::tests { + +TEST(LokiTests, ReferenceTest) { + PersistentFactory factory; + const auto object_0 = factory.get_or_create("object_0"); + const auto object_1 = factory.get_or_create("object_1"); + + ReferencedPDDLObjects references; + EXPECT_TRUE(!references.exists(object_0)); + EXPECT_TRUE(!references.exists(object_1)); + references.track(object_0); + EXPECT_TRUE(references.exists(object_0)); + references.track(object_1); + EXPECT_TRUE(references.exists(object_1)); + references.untrack(object_0); + EXPECT_TRUE(!references.exists(object_0)); +} + +} diff --git a/tests/common/pddl/segmented_vector.cpp b/tests/common/pddl/segmented_vector.cpp new file mode 100644 index 00000000..262c9049 --- /dev/null +++ b/tests/common/pddl/segmented_vector.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "../../../include/loki/common/pddl/segmented_vector.hpp" + + +namespace loki::domain::tests { + +TEST(LokiTests, SegmentedVectorTest) { + SegmentedVector vec; + EXPECT_EQ(vec.size(), 0); + EXPECT_EQ(vec.capacity(), 0); + + vec.push_back(2); + EXPECT_EQ(vec.size(), 1); + EXPECT_EQ(vec.capacity(), 2); + EXPECT_EQ(vec[0], 2); + + vec.push_back(1); + EXPECT_EQ(vec.size(), 2); + EXPECT_EQ(vec[1], 1); + EXPECT_EQ(vec.capacity(), 2); + + vec.push_back(0); + EXPECT_EQ(vec.size(), 3); + EXPECT_EQ(vec[2], 0); + EXPECT_EQ(vec.capacity(), 4); +} + +} diff --git a/tests/domain/CMakeLists.txt b/tests/domain/CMakeLists.txt new file mode 100644 index 00000000..a81161b5 --- /dev/null +++ b/tests/domain/CMakeLists.txt @@ -0,0 +1,11 @@ +file(GLOB SRC_FILES + "ast/*.cpp") + +add_executable(domain_tests ${SRC_FILES}) + +target_link_libraries(domain_tests + PRIVATE + loki::parsers + GTest::GTest) + +add_test(domain_gtests domain_tests) diff --git a/tests/domain/ast/atomic_formula_skeleton.cpp b/tests/domain/ast/atomic_formula_skeleton.cpp new file mode 100644 index 00000000..1fbb4cf6 --- /dev/null +++ b/tests/domain/ast/atomic_formula_skeleton.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "../../../src/domain/ast/parser.hpp" +#include "../../../include/loki/common/ast/parser_wrapper.hpp" +#include "../../../include/loki/domain/ast/printer.hpp" + + +namespace loki::domain::tests { + +TEST(LokiTests, AtomicFormulaSkeletonTest) { + ast::AtomicFormulaSkeleton ast; + + EXPECT_NO_THROW(parse_ast("(predicate1 ?var1 ?var2)", atomic_formula_skeleton(), ast)); + EXPECT_EQ(parse_text(ast), "(predicate1 ?var1 ?var2)"); + + EXPECT_NO_THROW(parse_ast("(predicate1 ?var1 - type1 ?var2 - type2)", atomic_formula_skeleton(), ast)); + EXPECT_EQ(parse_text(ast), "(predicate1 ?var1 - type1\n?var2 - type2)"); + + EXPECT_NO_THROW(parse_ast("(predicate1 ?var1 ?var2 - type1)", atomic_formula_skeleton(), ast)); + EXPECT_EQ(parse_text(ast), "(predicate1 ?var1 ?var2 - type1)"); + + EXPECT_ANY_THROW(parse_ast("(?var1 ?var2 - type1)", atomic_formula_skeleton(), ast)); +} + +} diff --git a/tests/domain/ast/atomic_function_skeleton.cpp b/tests/domain/ast/atomic_function_skeleton.cpp new file mode 100644 index 00000000..e7288276 --- /dev/null +++ b/tests/domain/ast/atomic_function_skeleton.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "../../../src/domain/ast/parser.hpp" +#include "../../../include/loki/common/ast/parser_wrapper.hpp" +#include "../../../include/loki/domain/ast/printer.hpp" + + +namespace loki::domain::tests { + +TEST(LokiTests, AtomicFunctionSkeletonTest) { + ast::AtomicFunctionSkeleton ast; + + EXPECT_NO_THROW(parse_ast("(function-symbol1 ?var1 ?var2)", atomic_function_skeleton(), ast)); + EXPECT_EQ(parse_text(ast), "(function-symbol1 ?var1 ?var2)"); + + EXPECT_NO_THROW(parse_ast("(function-symbol1 ?var1 - type1 ?var2 - type2)", atomic_function_skeleton(), ast)); + EXPECT_EQ(parse_text(ast), "(function-symbol1 ?var1 - type1\n?var2 - type2)"); + + EXPECT_NO_THROW(parse_ast("(function-symbol1 ?var1 ?var2 - type1)", atomic_function_skeleton(), ast)); + EXPECT_EQ(parse_text(ast), "(function-symbol1 ?var1 ?var2 - type1)"); + + EXPECT_ANY_THROW(parse_ast("(?var1 ?var2 - type1)", atomic_function_skeleton(), ast)); +} + +} diff --git a/tests/domain/ast/function_symbol.cpp b/tests/domain/ast/function_symbol.cpp new file mode 100644 index 00000000..bba58e4d --- /dev/null +++ b/tests/domain/ast/function_symbol.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "../../../src/domain/ast/parser.hpp" +#include "../../../include/loki/common/ast/parser_wrapper.hpp" +#include "../../../include/loki/domain/ast/printer.hpp" + + +namespace loki::domain::tests { + +TEST(LokiTests, FunctionSymbolTest) { + // A function symbol is just a name + ast::FunctionSymbol ast; + + EXPECT_NO_THROW(parse_ast("loki", function_symbol(), ast)); + EXPECT_EQ(parse_text(ast), "loki"); + EXPECT_NO_THROW(parse_ast("loki kilo", function_symbol(), ast)); + EXPECT_NO_THROW(parse_ast("loki", function_symbol(), ast)); + EXPECT_NO_THROW(parse_ast("loki(kilo)", function_symbol(), ast)); + EXPECT_EQ(parse_text(ast), "loki"); + + EXPECT_ANY_THROW(parse_ast("1loki", function_symbol(), ast)); + EXPECT_ANY_THROW(parse_ast("-loki", function_symbol(), ast)); + EXPECT_ANY_THROW(parse_ast("+loki", function_symbol(), ast)); + EXPECT_ANY_THROW(parse_ast("*loki", function_symbol(), ast)); + EXPECT_ANY_THROW(parse_ast("/loki", function_symbol(), ast)); + EXPECT_ANY_THROW(parse_ast("?loki", function_symbol(), ast)); +} + +} diff --git a/tests/domain/ast/function_symbol_total_cost.cpp b/tests/domain/ast/function_symbol_total_cost.cpp new file mode 100644 index 00000000..ce63d24e --- /dev/null +++ b/tests/domain/ast/function_symbol_total_cost.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "../../../src/domain/ast/parser.hpp" +#include "../../../include/loki/common/ast/parser_wrapper.hpp" +#include "../../../include/loki/domain/ast/printer.hpp" + + +namespace loki::domain::tests { + +TEST(LokiTests, FunctionSymbolTotalCostTest) { + ast::FunctionSymbol ast; + + EXPECT_NO_THROW(parse_ast("total-cost ", function_symbol_total_cost(), ast)); + EXPECT_EQ(parse_text(ast), "total-cost"); + EXPECT_NO_THROW(parse_ast("total-cost(", function_symbol_total_cost(), ast)); + EXPECT_NO_THROW(parse_ast("total-cost)", function_symbol_total_cost(), ast)); + EXPECT_NO_THROW(parse_ast("total-cost\n", function_symbol_total_cost(), ast)); + + // no separator after "total-cost" keyword + EXPECT_ANY_THROW(parse_ast("total-cost", function_symbol_total_cost(), ast)); // no separator + // wrong keyword + EXPECT_ANY_THROW(parse_ast("loki ", function_symbol_total_cost(), ast)); +} + +} diff --git a/tests/domain/ast/function_typed_list_of_atom_function_skeletons.cpp b/tests/domain/ast/function_typed_list_of_atom_function_skeletons.cpp new file mode 100644 index 00000000..e13f9c8f --- /dev/null +++ b/tests/domain/ast/function_typed_list_of_atom_function_skeletons.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "../../../src/domain/ast/parser.hpp" +#include "../../../include/loki/common/ast/parser_wrapper.hpp" +#include "../../../include/loki/domain/ast/printer.hpp" + + +namespace loki::domain::tests { + +TEST(LokiTests, FunctionTypedListOfAtomicFunctionSkeletonsTest) { + ast::FunctionTypedListOfAtomicFunctionSkeletons ast; + + EXPECT_NO_THROW(parse_ast("(function-symbol1 ?var1 ?var2) - number ", function_typed_list_of_atomic_function_skeletons(), ast)); + EXPECT_EQ(parse_text(ast), "(function-symbol1 ?var1 ?var2) - number"); + EXPECT_NO_THROW(parse_ast("(function-symbol1 ?var1 ?var2) - number)", function_typed_list_of_atomic_function_skeletons(), ast)); + EXPECT_NO_THROW(parse_ast("(function-symbol1 ?var1 ?var2) - number\n", function_typed_list_of_atomic_function_skeletons(), ast)); + + // trailing "(" indicates another atomic function skeleton that fails to be parsed. + EXPECT_ANY_THROW(parse_ast("(function-symbol1 ?var1 ?var2) - number(", function_typed_list_of_atomic_function_skeletons(), ast)); + // no trailing separator after "number" keyword + EXPECT_ANY_THROW(parse_ast("(function-symbol1 ?var1 ?var2) - number", function_typed_list_of_atomic_function_skeletons(), ast)); + // function type does not match "number" + EXPECT_ANY_THROW(parse_ast("(function-symbol1 ?var1 ?var2) - wrong ", function_typed_list_of_atomic_function_skeletons(), ast)); +} + +} diff --git a/tests/domain/ast/name.cpp b/tests/domain/ast/name.cpp new file mode 100644 index 00000000..1099619c --- /dev/null +++ b/tests/domain/ast/name.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "../../../src/domain/ast/parser.hpp" +#include "../../../include/loki/common/ast/parser_wrapper.hpp" +#include "../../../include/loki/domain/ast/printer.hpp" + + +namespace loki::domain::tests { + +TEST(LokiTests, NameTest) { + ast::Name ast; + + EXPECT_NO_THROW(parse_ast("loki", name(), ast)); + EXPECT_EQ(parse_text(ast), "loki"); + EXPECT_NO_THROW(parse_ast("loki kilo", name(), ast)); + EXPECT_NO_THROW(parse_ast("loki", name(), ast)); + EXPECT_NO_THROW(parse_ast("loki(kilo)", name(), ast)); + EXPECT_EQ(parse_text(ast), "loki"); + + EXPECT_ANY_THROW(parse_ast("1loki", name(), ast)); + EXPECT_ANY_THROW(parse_ast("-loki", name(), ast)); + EXPECT_ANY_THROW(parse_ast("+loki", name(), ast)); + EXPECT_ANY_THROW(parse_ast("*loki", name(), ast)); + EXPECT_ANY_THROW(parse_ast("/loki", name(), ast)); + EXPECT_ANY_THROW(parse_ast("?loki", name(), ast)); +} + +} diff --git a/tests/domain/ast/number.cpp b/tests/domain/ast/number.cpp new file mode 100644 index 00000000..aa85392a --- /dev/null +++ b/tests/domain/ast/number.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "../../../src/domain/ast/parser.hpp" +#include "../../../include/loki/common/ast/parser_wrapper.hpp" +#include "../../../include/loki/domain/ast/printer.hpp" + + +namespace loki::domain::tests { + +TEST(LokiTests, NumberTest) { + ast::Number ast; + + EXPECT_NO_THROW(parse_ast("5", number(), ast)); + EXPECT_EQ(parse_text(ast), "5"); + EXPECT_NO_THROW(parse_ast("4.2", number(), ast)); + EXPECT_EQ(parse_text(ast), "4.2"); + EXPECT_NO_THROW(parse_ast("6 7", number(), ast)); + EXPECT_EQ(parse_text(ast), "6"); + // TODO: Is this really what we want? + EXPECT_NO_THROW(parse_ast("1loki", number(), ast)); + EXPECT_EQ(parse_text(ast), "1"); + + EXPECT_ANY_THROW(parse_ast("loki", number(), ast)); + EXPECT_ANY_THROW(parse_ast("(5)", number(), ast)); +} + +} diff --git a/tests/domain/ast/predicate.cpp b/tests/domain/ast/predicate.cpp new file mode 100644 index 00000000..13af4715 --- /dev/null +++ b/tests/domain/ast/predicate.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "../../../src/domain/ast/parser.hpp" +#include "../../../include/loki/common/ast/parser_wrapper.hpp" +#include "../../../include/loki/domain/ast/printer.hpp" + + +namespace loki::domain::tests { + +TEST(LokiTests, PredicateTest) { + // A predicate is just a name + ast::Predicate ast; + + EXPECT_NO_THROW(parse_ast("loki", predicate(), ast)); + EXPECT_EQ(parse_text(ast), "loki"); + EXPECT_NO_THROW(parse_ast("loki kilo", predicate(), ast)); + EXPECT_NO_THROW(parse_ast("loki", predicate(), ast)); + EXPECT_NO_THROW(parse_ast("loki(kilo)", predicate(), ast)); + EXPECT_EQ(parse_text(ast), "loki"); + + EXPECT_ANY_THROW(parse_ast("1loki", predicate(), ast)); + EXPECT_ANY_THROW(parse_ast("-loki", predicate(), ast)); + EXPECT_ANY_THROW(parse_ast("+loki", predicate(), ast)); + EXPECT_ANY_THROW(parse_ast("*loki", predicate(), ast)); + EXPECT_ANY_THROW(parse_ast("/loki", predicate(), ast)); + EXPECT_ANY_THROW(parse_ast("?loki", predicate(), ast)); +} + +} diff --git a/tests/domain/ast/term.cpp b/tests/domain/ast/term.cpp new file mode 100644 index 00000000..a4b3ef22 --- /dev/null +++ b/tests/domain/ast/term.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "../../../src/domain/ast/parser.hpp" +#include "../../../include/loki/common/ast/parser_wrapper.hpp" +#include "../../../include/loki/domain/ast/printer.hpp" + + +namespace loki::domain::tests { + +TEST(LokiTests, TermTest) { + ast::Term ast; + + EXPECT_NO_THROW(parse_ast("?loki", term(), ast)); + EXPECT_EQ(parse_text(ast), "?loki"); + EXPECT_NO_THROW(parse_ast("loki", term(), ast)); + EXPECT_EQ(parse_text(ast), "loki"); + EXPECT_NO_THROW(parse_ast("?loki(?kilo)", term(), ast)); + EXPECT_EQ(parse_text(ast), "?loki"); + EXPECT_NO_THROW(parse_ast("loki(kilo)", term(), ast)); + EXPECT_EQ(parse_text(ast), "loki"); + + EXPECT_ANY_THROW(parse_ast("1loki", term(), ast)); + EXPECT_ANY_THROW(parse_ast("-loki", term(), ast)); + EXPECT_ANY_THROW(parse_ast("+loki", term(), ast)); + EXPECT_ANY_THROW(parse_ast("*loki", term(), ast)); + EXPECT_ANY_THROW(parse_ast("/loki", term(), ast)); +} + +} diff --git a/tests/domain/ast/type.cpp b/tests/domain/ast/type.cpp new file mode 100644 index 00000000..4254ecb8 --- /dev/null +++ b/tests/domain/ast/type.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "../../../src/domain/ast/parser.hpp" +#include "../../../include/loki/common/ast/parser_wrapper.hpp" +#include "../../../include/loki/domain/ast/printer.hpp" + + +namespace loki::domain::tests { + +TEST(LokiTests, TypeTest) { + ast::Type ast; + + EXPECT_NO_THROW(parse_ast("(either type1 type2)", type(), ast)); + EXPECT_EQ(parse_text(ast), "(either type1 type2)"); + EXPECT_NO_THROW(parse_ast("(either type1 (either type2 type3))", type(), ast)); + EXPECT_EQ(parse_text(ast), "(either type1 (either type2 type3))"); + + EXPECT_NO_THROW(parse_ast("either", type(), ast)); // type either expects parenthesis around +} + +} diff --git a/tests/domain/ast/type_either.cpp b/tests/domain/ast/type_either.cpp new file mode 100644 index 00000000..48b9ee43 --- /dev/null +++ b/tests/domain/ast/type_either.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "../../../src/domain/ast/parser.hpp" +#include "../../../include/loki/common/ast/parser_wrapper.hpp" +#include "../../../include/loki/domain/ast/printer.hpp" + + +namespace loki::domain::tests { + +TEST(LokiTests, TypeEitherTest) { + ast::TypeEither ast; + + EXPECT_NO_THROW(parse_ast("(either type1 type2)", type_either(), ast)); + EXPECT_EQ(parse_text(ast), "(either type1 type2)"); + EXPECT_NO_THROW(parse_ast("(either type1 (either type2 type3))", type_either(), ast)); + EXPECT_EQ(parse_text(ast), "(either type1 (either type2 type3))"); + + EXPECT_ANY_THROW(parse_ast("either", type_either(), ast)); // can be parsed into name +} + +} diff --git a/tests/domain/ast/typed_list_of_names.cpp b/tests/domain/ast/typed_list_of_names.cpp new file mode 100644 index 00000000..c029afe1 --- /dev/null +++ b/tests/domain/ast/typed_list_of_names.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "../../../src/domain/ast/parser.hpp" +#include "../../../include/loki/common/ast/parser_wrapper.hpp" +#include "../../../include/loki/domain/ast/printer.hpp" + + +namespace loki::domain::tests { + +TEST(LokiTests, TypedListOfNamesTest) { + ast::TypedListOfNames ast; + + EXPECT_NO_THROW(parse_ast("name1 name2 - type1 name3 name4 - type2", typed_list_of_names(), ast)); + EXPECT_EQ(parse_text(ast), "name1 name2 - type1\nname3 name4 - type2"); + + EXPECT_NO_THROW(parse_ast("name1 name2", typed_list_of_names(), ast)); + EXPECT_EQ(parse_text(ast), "name1 name2"); + + EXPECT_NO_THROW(parse_ast("?var1 ?var2", typed_list_of_names(), ast)); + EXPECT_EQ(parse_text(ast), ""); + + EXPECT_NO_THROW(parse_ast("- type1", typed_list_of_names(), ast)); + EXPECT_EQ(parse_text(ast), ""); +} + +} diff --git a/tests/domain/ast/typed_list_of_names_recursively.cpp b/tests/domain/ast/typed_list_of_names_recursively.cpp new file mode 100644 index 00000000..fac926cf --- /dev/null +++ b/tests/domain/ast/typed_list_of_names_recursively.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "../../../src/domain/ast/parser.hpp" +#include "../../../include/loki/common/ast/parser_wrapper.hpp" +#include "../../../include/loki/domain/ast/printer.hpp" + + +namespace loki::domain::tests { + +TEST(LokiTests, TypedListOfNamesRecursivelyTest) { + ast::TypedListOfNamesRecursively ast; + + EXPECT_NO_THROW(parse_ast("name1 name2 - type1", typed_list_of_names_recursively(), ast)); + EXPECT_EQ(parse_text(ast), "name1 name2 - type1"); + + EXPECT_ANY_THROW(parse_ast("name1 name2", typed_list_of_names_recursively(), ast)); + EXPECT_ANY_THROW(parse_ast("?var1 ?var2", typed_list_of_names_recursively(), ast)); +} + +} diff --git a/tests/domain/ast/typed_list_of_variables.cpp b/tests/domain/ast/typed_list_of_variables.cpp new file mode 100644 index 00000000..b9792c48 --- /dev/null +++ b/tests/domain/ast/typed_list_of_variables.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "../../../src/domain/ast/parser.hpp" +#include "../../../include/loki/common/ast/parser_wrapper.hpp" +#include "../../../include/loki/domain/ast/printer.hpp" + + +namespace loki::domain::tests { + +TEST(LokiTests, TypedListOfVariablesTest) { + ast::TypedListOfVariables ast; + + EXPECT_NO_THROW(parse_ast("?var1 ?var2 - type1 ?var3 ?var4 - type2", typed_list_of_variables(), ast)); + EXPECT_EQ(parse_text(ast), "?var1 ?var2 - type1\n?var3 ?var4 - type2"); + + EXPECT_NO_THROW(parse_ast("?var1 ?var2", typed_list_of_variables(), ast)); + EXPECT_EQ(parse_text(ast), "?var1 ?var2"); + + EXPECT_NO_THROW(parse_ast("name1 name2", typed_list_of_variables(), ast)); + EXPECT_EQ(parse_text(ast), ""); + + EXPECT_NO_THROW(parse_ast("- type1", typed_list_of_variables(), ast)); + EXPECT_EQ(parse_text(ast), ""); +} + +} diff --git a/tests/domain/ast/typed_list_of_variables_recursively.cpp b/tests/domain/ast/typed_list_of_variables_recursively.cpp new file mode 100644 index 00000000..45f85447 --- /dev/null +++ b/tests/domain/ast/typed_list_of_variables_recursively.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "../../../src/domain/ast/parser.hpp" +#include "../../../include/loki/common/ast/parser_wrapper.hpp" +#include "../../../include/loki/domain/ast/printer.hpp" + + +namespace loki::domain::tests { + +TEST(LokiTests, TypedListOfVariablesRecursivelyTest) { + ast::TypedListOfVariablesRecursively ast; + + EXPECT_NO_THROW(parse_ast("?var1 ?var2 - type1", typed_list_of_variables_recursively(), ast)); + EXPECT_EQ(parse_text(ast), "?var1 ?var2 - type1"); + + EXPECT_ANY_THROW(parse_ast("name1 name2", typed_list_of_variables_recursively(), ast)); + EXPECT_ANY_THROW(parse_ast("?var1 ?var2", typed_list_of_variables_recursively(), ast)); +} + +} diff --git a/tests/domain/ast/variable.cpp b/tests/domain/ast/variable.cpp new file mode 100644 index 00000000..ea0b71d3 --- /dev/null +++ b/tests/domain/ast/variable.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2023 Dominik Drexler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "../../../src/domain/ast/parser.hpp" +#include "../../../include/loki/common/ast/parser_wrapper.hpp" +#include "../../../include/loki/domain/ast/printer.hpp" + + +namespace loki::domain::tests { + +TEST(LokiTests, VariableTest) { + ast::Variable ast; + + EXPECT_NO_THROW(parse_ast("?loki", variable(), ast)); + EXPECT_EQ(parse_text(ast), "?loki"); + EXPECT_NO_THROW(parse_ast("?loki ?kilo", variable(), ast)); + EXPECT_EQ(parse_text(ast), "?loki"); + EXPECT_NO_THROW(parse_ast("?loki(?kilo)", variable(), ast)); + EXPECT_EQ(parse_text(ast), "?loki"); + + EXPECT_ANY_THROW(parse_ast("loki", variable(), ast)); + EXPECT_ANY_THROW(parse_ast("1loki", variable(), ast)); + EXPECT_ANY_THROW(parse_ast("-loki", variable(), ast)); + EXPECT_ANY_THROW(parse_ast("+loki", variable(), ast)); + EXPECT_ANY_THROW(parse_ast("*loki", variable(), ast)); + EXPECT_ANY_THROW(parse_ast("/loki", variable(), ast)); +} + +}