diff --git a/.gitmodules b/.gitmodules index 44d6d26..b4b58b4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,3 @@ -[submodule "tests/googletest"] - path = tests/googletest - url = https://github.com/google/googletest.git - ignore = dirty +[submodule "lib/catch"] + path = lib/catch + url = https://github.com/philsquared/Catch diff --git a/.travis.yml b/.travis.yml index d3409a1..f4873f3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,25 +1,46 @@ # Use container-based distribution sudo: false language: c++ +addons: + apt: + sources: &default_sources + - ubuntu-toolchain-r-test + - boost-latest + packages: &default_packages + - libboost-program-options1.55-dev + - libboost-iostreams1.55-dev + - libboost-system1.55-dev + - libboost-filesystem1.55-dev matrix: include: - - compiler: gcc + - env: COMPILER_NAME=g++ _CXX=g++-5 + os: linux + language: cpp addons: apt: sources: - - ubuntu-toolchain-r-test - - boost-latest + - *default_sources packages: + - *default_packages - g++-5 - - libboost-program-options1.55-dev - - libboost-iostreams1.55-dev - - libboost-system1.55-dev - - libboost-filesystem1.55-dev - env: COMPILER=g++-5 + - env: COMPILER_NAME=g++ _CXX=g++-6 + os: linux + language: cpp + addons: + apt: + sources: + - *default_sources + packages: + - *default_packages + - g++-6 script: - - git submodule init - - git submodule update - - mkdir build - - cd build - - cmake .. -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTS=ON -DCMAKE_CXX_COMPILER=$COMPILER - - make -j3 && make -j3 run-tests + - if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then + CMAKE_URL="http://www.cmake.org/files/v3.7/cmake-3.7.0-Linux-x86_64.tar.gz"; + mkdir cmake-bin && wget --quiet --no-check-certificate -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake-bin; + export PATH=${PWD}/cmake-bin/bin:${PATH}; + fi + - git submodule update --recursive --init + - mkdir -p build/debug + - cd build/debug + - cmake ../.. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=$_CXX -DPLASP_BUILD_TESTS=ON + - make -j3 plasp-app && make -j3 run-tests diff --git a/CHANGELOG.md b/CHANGELOG.md index d947e58..c03c7d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ Features: * extended PDDL parser support (`imply`, `exists`, `forall`, and `when` expressions) +* improved command-line interface +* new command-line option `--log-level` to control which status messages should be shown +* new command-line option `--warnings-as-errors` to abort program execution upon warnings (replaces `--warning-level`) ## 3.0.3 (2016-09-02) diff --git a/CMakeLists.txt b/CMakeLists.txt index 27630e3..33b7ff9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,20 +1,23 @@ cmake_minimum_required(VERSION 2.6) project(plasp CXX) +option(PLASP_BUILD_TESTS "Build unit tests" OFF) + find_package(Boost 1.55.0 COMPONENTS program_options iostreams system filesystem REQUIRED) set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wpedantic") set(CMAKE_CXX_FLAGS_DEBUG "-g") -add_definitions(-std=c++14) -option(BUILD_TESTS "Build unit tests" OFF) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) add_subdirectory(src) -add_subdirectory(apps) -if(BUILD_TESTS) +add_subdirectory(app) +if(PLASP_BUILD_TESTS) add_subdirectory(tests) -endif(BUILD_TESTS) +endif(PLASP_BUILD_TESTS) diff --git a/README.md b/README.md index 3d594ec..a48da59 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# plasp—Translate PDDL to ASP +# plasp [![GitHub Release](https://img.shields.io/github/release/potassco/plasp.svg?maxAge=3600)](https://github.com/potassco/plasp/releases) [![Build Status](https://img.shields.io/travis/potassco/plasp/master.svg?maxAge=3600&label=build (master))](https://travis-ci.org/potassco/plasp?branch=master) [![Build Status](https://img.shields.io/travis/potassco/plasp/develop.svg?maxAge=3600&label=build (develop))](https://travis-ci.org/potassco/plasp?branch=develop) -[![GitHub Release](https://img.shields.io/github/release/potassco/plasp.svg?maxAge=3600)](https://github.com/potassco/plasp/releases) -[![Build Status](https://img.shields.io/travis/potassco/plasp/develop.svg?maxAge=3600&label=build (master))](https://travis-ci.org/potassco/plasp?branch=master) -[![Build Status](https://img.shields.io/travis/potassco/plasp/develop.svg?maxAge=3600&label=build (develop))](https://travis-ci.org/potassco/plasp?branch=develop) +> Translate PDDL to ASP + +## Overview `plasp` 3 is in early development and not intended for productive use yet. @@ -45,7 +45,7 @@ $ clingo encodings/sequential-incremental.lp instance.lp ## Command-Line Interface ```bash -$ plasp [files] [options] +$ plasp [options] file... ``` `plasp` automatically detects the language of the input program. @@ -64,11 +64,13 @@ If you want to write your own meta encoding for `plasp`’s output, this [simple `plasp` requires `boost` and is built via CMake and a C++ compiler. -See [building instructions](doc/building-instructions.md) for more details. +See [building](doc/building.md) for more details. ## Contributors -* [Patrick Lühne](https://www.luehne.de) (`plasp` 3) +* [Patrick Lühne](https://www.luehne.de) +* Martin Gebser (encodings) +* Torsten Schaub (encodings) ### Earlier Versions diff --git a/apps/plasp-app/CMakeLists.txt b/app/CMakeLists.txt similarity index 79% rename from apps/plasp-app/CMakeLists.txt rename to app/CMakeLists.txt index b6a4ca9..7682090 100644 --- a/apps/plasp-app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -1,4 +1,4 @@ -set(target plasp_app) +set(target plasp-app) file(GLOB core_sources "*.cpp") file(GLOB core_headers "*.h") @@ -20,4 +20,4 @@ set(libraries add_executable(${target} ${sources}) target_link_libraries(${target} ${libraries}) -set_target_properties(plasp_app PROPERTIES OUTPUT_NAME plasp) +set_target_properties(${target} PROPERTIES OUTPUT_NAME plasp) diff --git a/apps/plasp-app/main.cpp b/app/main.cpp similarity index 51% rename from apps/plasp-app/main.cpp rename to app/main.cpp index f58f5f9..e4f3029 100644 --- a/apps/plasp-app/main.cpp +++ b/app/main.cpp @@ -5,25 +5,28 @@ #include #include +#include +#include #include #include #include #include -#include -#include int main(int argc, char **argv) { namespace po = boost::program_options; + bool warningsAsErrors; + po::options_description description("Allowed options"); description.add_options() - ("help,h", "Display this help message.") - ("version,v", "Display version information.") - ("input,i", po::value>(), "Specify the PDDL or SAS input file.") - ("language,l", po::value(), "Specify the input language (sas or pddl). Omit for automatic detection.") - ("warning-level", po::value()->default_value("normal"), "Specify whether to output warnings normally (normal), to treat them as critical errors (error), or to ignore them (ignore).") - ("color", po::value()->default_value("auto"), "Specify whether to colorize the output (always, never, or auto)."); + ("help,h", "Display this help message") + ("version,v", "Display version information") + ("input,i", po::value>(), "Input files (in PDDL or SAS format)") + ("language,l", po::value()->default_value("auto"), "Input language (pddl, sas, auto)") + ("color", po::value()->default_value("auto"), "Colorize output (always, never, auto)") + ("log-priority,p", po::value()->default_value("warning"), "Log messages starting from this priority (debug, info, warning, error)") + ("warnings-as-errors", po::bool_switch(&warningsAsErrors), "Treat warnings as errors"); po::positional_options_description positionalOptionsDescription; positionalOptionsDescription.add("input", -1); @@ -33,13 +36,13 @@ int main(int argc, char **argv) const auto printHelp = [&]() { - std::cout << "Usage: plasp [files] [options]" << std::endl; - std::cout << "Translate PDDL instances to ASP facts." << std::endl << std::endl; + std::cout << "Usage: plasp [options] file..." << std::endl; + std::cout << "Translate PDDL to ASP." << std::endl << std::endl; std::cout << description; }; - plasp::utils::Logger logger; + plasp::output::Logger logger; try { @@ -52,7 +55,7 @@ int main(int argc, char **argv) } catch (const po::error &e) { - logger.logError(e.what()); + logger.log(plasp::output::Priority::Error, e.what()); std::cout << std::endl; printHelp(); return EXIT_FAILURE; @@ -70,41 +73,43 @@ int main(int argc, char **argv) return EXIT_SUCCESS; } - const auto warningLevel = variablesMap["warning-level"].as(); + if (warningsAsErrors) + logger.setAbortPriority(plasp::output::Priority::Warning); - if (warningLevel == "error") - logger.setWarningLevel(plasp::utils::Logger::WarningLevel::Error); - else if (warningLevel == "ignore") - logger.setWarningLevel(plasp::utils::Logger::WarningLevel::Ignore); - else if (warningLevel == "normal") - logger.setWarningLevel(plasp::utils::Logger::WarningLevel::Normal); + const auto colorPolicy = variablesMap["color"].as(); + + if (colorPolicy == "auto") + logger.setColorPolicy(plasp::output::ColorStream::ColorPolicy::Auto); + else if (colorPolicy == "never") + logger.setColorPolicy(plasp::output::ColorStream::ColorPolicy::Never); + else if (colorPolicy == "always") + logger.setColorPolicy(plasp::output::ColorStream::ColorPolicy::Always); else { - logger.logError("unknown warning level “" + warningLevel + "”"); + logger.log(plasp::output::Priority::Error, "unknown color policy “" + colorPolicy + "”"); std::cout << std::endl; printHelp(); return EXIT_FAILURE; } - const auto colorPolicy = variablesMap["color"].as(); + const auto logPriorityString = variablesMap["log-priority"].as(); - if (colorPolicy == "auto") - logger.setColorPolicy(plasp::utils::LogStream::ColorPolicy::Auto); - else if (colorPolicy == "never") - logger.setColorPolicy(plasp::utils::LogStream::ColorPolicy::Never); - else if (colorPolicy == "always") - logger.setColorPolicy(plasp::utils::LogStream::ColorPolicy::Always); - else + try { - logger.logError("unknown color policy “" + colorPolicy + "”"); - std::cout << std::endl; + const auto logPriority = plasp::output::priorityFromName(logPriorityString.c_str()); + logger.setLogPriority(logPriority); + } + catch (const std::exception &e) + { + logger.log(plasp::output::Priority::Error, ("unknown log priorty “" + logPriorityString + "”").c_str()); + logger.errorStream() << std::endl; printHelp(); return EXIT_FAILURE; } try { - plasp::utils::Parser parser; + plasp::input::Parser parser; if (variablesMap.count("input")) { @@ -122,19 +127,20 @@ int main(int argc, char **argv) const auto detectLanguage = [&]() { - if (variablesMap.count("language") == 0) + const auto languageName = variablesMap["language"].as(); + const auto language = plasp::Language::fromString(languageName); + + if (language == plasp::Language::Type::Automatic) return plasp::detectLanguage(parser); - const auto languageName = variablesMap["language"].as(); - - return plasp::Language::fromString(languageName); + return language; }; const auto language = detectLanguage(); if (language == plasp::Language::Type::Unknown) { - logger.logError("unknown input language"); + logger.log(plasp::output::Priority::Error, "unknown input language"); std::cout << std::endl; printHelp(); return EXIT_FAILURE; @@ -142,10 +148,9 @@ int main(int argc, char **argv) if (language == plasp::Language::Type::PDDL) { - auto pddlLogger = logger; - auto context = plasp::pddl::Context(std::move(parser), std::move(pddlLogger)); - auto description = plasp::pddl::Description::fromContext(std::move(context)); - const auto translator = plasp::pddl::TranslatorASP(description, description.context().logger.outputStream()); + auto context = plasp::pddl::Context(std::move(parser), logger); + auto description = plasp::pddl::Description::fromContext(context); + const auto translator = plasp::pddl::TranslatorASP(description, logger.outputStream()); translator.translate(); } else if (language == plasp::Language::Type::SAS) @@ -155,19 +160,19 @@ int main(int argc, char **argv) translator.translate(); } } - catch (const plasp::utils::ParserException &e) + catch (const plasp::input::ParserException &e) { - logger.logError(e.coordinate(), e.message()); + logger.log(plasp::output::Priority::Error, e.location(), e.message().c_str()); return EXIT_FAILURE; } - catch (const plasp::utils::TranslatorException &e) + catch (const plasp::output::TranslatorException &e) { - logger.logError(e.what()); + logger.log(plasp::output::Priority::Error, e.what()); return EXIT_FAILURE; } catch (const std::exception &e) { - logger.logError(e.what()); + logger.log(plasp::output::Priority::Error, e.what()); return EXIT_FAILURE; } diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt deleted file mode 100644 index f30b3d4..0000000 --- a/apps/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_subdirectory(plasp-app) diff --git a/doc/building-instructions.md b/doc/building.md similarity index 85% rename from doc/building-instructions.md rename to doc/building.md index 3f56a48..8bc91b4 100644 --- a/doc/building-instructions.md +++ b/doc/building.md @@ -1,4 +1,4 @@ -# Building Instructions +# Building `plasp` requires a C++14 compiler (preferrably GCC ≥ 6.1 or clang ≥ 3.8), the `boost` libraries (≥ 1.55), and CMake for building. @@ -25,8 +25,8 @@ $ make ## Running the Tests -`plasp` provides unit tests written using the [Google Test](https://github.com/google/googletest) framework. -Before building and running the tests, make sure you have fetched the Google Test git submodule: +`plasp` provides unit tests written using the [Catch](https://github.com/philsquared/Catch) framework. +Before building and running the tests, make sure you have fetched the Catch git submodule: ```bash $ git submodule init diff --git a/doc/command-line-interface.md b/doc/command-line-interface.md index 03f48b4..0ea57ca 100644 --- a/doc/command-line-interface.md +++ b/doc/command-line-interface.md @@ -1,18 +1,18 @@ # Command-Line Interface ```bash -$ plasp [files] [options] +$ plasp [options] file... ``` `plasp` automatically detects the language of the input files. Multiple files may be provided in an arbitrary order. -`[files]` may also be omitted, in which case the input is read from `std::cin`. +The `file...` arguments may also be omitted, in which case the input is read from `std::cin`. `plasp` supports the following options: -| **option** | **explanation** | -|-----------------------------------|-----------------------------------------------------------------------------------------------------------------------------------| -| `-l` [ `--language` ] | Specify the input language (`sas` or `pddl`). Omit for automatic detection. | -| `--warning-level` arg (=`normal`) | Specify whether to output warnings normally (`normal`), to treat them as critical errors (`error`), or to ignore them (`ignore`). | -| `--color` arg (=`auto`) | Specify whether to colorize the output (`always`, `never`, or `auto`). | +| **option** | **explanation** | +|------------|-----------------| +| `-l` [ `--language` ] arg (=`auto`) | Input language (`pddl`, `sas`, `auto`) | +| `--warning-level` arg (=`show`) | Show warnings (`show`), treat them as errors (`error`), or ignore them (`ignore`) | +| `--color` arg (=`auto`) | Colorize output (`always`, `never`, `auto`) | diff --git a/encodings/sequential-horizon.lp b/encodings/sequential-horizon.lp new file mode 100644 index 0000000..135a22e --- /dev/null +++ b/encodings/sequential-horizon.lp @@ -0,0 +1,36 @@ +#const horizon=1. + +% Check feature requirements +:- requires(feature(actionCosts)). +:- requires(feature(axiomRules)). +:- requires(feature(conditionalEffects)). + +% Horizon, must be defined externally +time(0..horizon). + +% Establish initial state +holds(Variable, Value, 0) :- initialState(Variable, Value). + +% Perform actions +1 {occurs(Action, T) : action(Action)} 1 :- time(T), T > 0. + +% Check preconditions +:- occurs(Action, T), precondition(Action, Variable, Value), not holds(Variable, Value, T - 1), time(T), time(T - 1). + +% Apply effects +caused(Variable, Value, T) :- occurs(Action, T), postcondition(Action, _, Variable, Value). +modified(Variable, T) :- caused(Variable, Value, T). + +holds(Variable, Value, T) :- caused(Variable, Value, T), time(T). +holds(Variable, Value, T) :- holds(Variable, Value, T - 1), not modified(Variable, T), time(T), time(T - 1). + +% Check that variables have unique values +:- variable(Variable), not 1 {holds(Variable, Value, T) : contains(Variable, Value)} 1, time(T). + +% Check mutexes +:- mutexGroup(MutexGroup), not {holds(Variable, Value, T) : contains(MutexGroup, Variable, Value)} 1, time(T). + +% Verify that goal is met +:- goal(Variable, Value), not holds(Variable, Value, horizon). + +#show occurs/2. diff --git a/encodings/strips/README.md b/encodings/strips/README.md new file mode 100644 index 0000000..037ce05 --- /dev/null +++ b/encodings/strips/README.md @@ -0,0 +1,56 @@ +# Incremental STRIPS Planning Encodings + +This suite of incremental STRIPS planning encodings implements diverse methods. +The included encoding files provide the following functionalities: + +## Encodings + +### [preprocess.lp](preprocess.lp): static analysis of potentially relevant actions + +* Parameters: `_closure` (default value: `3`) + * Value `1`: forward chaining of effects w.r.t. initial variable values + * Value `2`: backward regression of effects w.r.t. goal variable values + * Value `3`: both forward chaining and backward regression of effects + * Otherwise: off (simply take all actions as given) + +### [strips-incremental.lp](strips-incremental.lp): sequential and parallel planning encoding variants +* Parameters: `_parallel` (default value: `0`) + * Value `1`: “forall” parallel actions that can be arranged in any sequence + * Value `2`: “exists” parallel actions that can be arranged in some sequence + * Otherwise: sequential actions + +### [redundancy.lp](redundancy.lp): enforcement of ‘redundant’ actions to constrain parallel plans +* Remarks: + * Only relevant together with parallel actions + * Encoded constraints seem rather ineffective though + * Heavy space overhead in combination with “exists” parallel actions + +### [postprocess.lp](postprocess.lp): plan feasibility checking and conversion to sequential plan + +## Usage Examples + +Some example invocations (using `clingo` 5.1.0) are as follows: + +```bash +plasp ../../instances/PDDL/ipc-2000-elevator-m10-strips/domain.pddl ../../instances/PDDL/ipc-2000-elevator-m10-strips/problem-04-00.pddl | clingo - preprocess.lp strips-incremental.lp + +plasp ../../instances/PDDL/ipc-2000-elevator-m10-strips/domain.pddl ../../instances/PDDL/ipc-2000-elevator-m10-strips/problem-04-00.pddl | clingo - preprocess.lp strips-incremental.lp -c _closure=0 + +plasp ../../instances/PDDL/ipc-2000-elevator-m10-strips/domain.pddl ../../instances/PDDL/ipc-2000-elevator-m10-strips/problem-04-00.pddl | clingo - preprocess.lp strips-incremental.lp -c _closure=1 + +plasp ../../instances/PDDL/ipc-2000-elevator-m10-strips/domain.pddl ../../instances/PDDL/ipc-2000-elevator-m10-strips/problem-04-00.pddl | clingo - preprocess.lp strips-incremental.lp -c _closure=2 + +plasp ../../instances/PDDL/ipc-2000-elevator-m10-strips/domain.pddl ../../instances/PDDL/ipc-2000-elevator-m10-strips/problem-04-00.pddl | clingo - preprocess.lp strips-incremental.lp -c _parallel=1 + +plasp ../../instances/PDDL/ipc-2000-elevator-m10-strips/domain.pddl ../../instances/PDDL/ipc-2000-elevator-m10-strips/problem-04-00.pddl | clingo - preprocess.lp strips-incremental.lp -c _parallel=2 + +plasp ../../instances/PDDL/ipc-2000-elevator-m10-strips/domain.pddl ../../instances/PDDL/ipc-2000-elevator-m10-strips/problem-04-00.pddl | clingo - preprocess.lp strips-incremental.lp -c _parallel=1 redundancy.lp + +plasp ../../instances/PDDL/ipc-2000-elevator-m10-strips/domain.pddl ../../instances/PDDL/ipc-2000-elevator-m10-strips/problem-04-00.pddl | clingo - preprocess.lp strips-incremental.lp -c _parallel=2 redundancy.lp + +plasp ../../instances/PDDL/ipc-2000-elevator-m10-strips/domain.pddl ../../instances/PDDL/ipc-2000-elevator-m10-strips/problem-04-00.pddl | clingo - preprocess.lp strips-incremental.lp --outf=1 | grep -A1 -e "ANSWER" | tail -n1 | clingo - postprocess.lp <(plasp ../../instances/PDDL/ipc-2000-elevator-m10-strips/domain.pddl ../../instances/PDDL/ipc-2000-elevator-m10-strips/problem-04-00.pddl) + +plasp ../../instances/PDDL/ipc-2000-elevator-m10-strips/domain.pddl ../../instances/PDDL/ipc-2000-elevator-m10-strips/problem-04-00.pddl | clingo - preprocess.lp strips-incremental.lp --outf=1 -c _parallel=1 | grep -A1 -e "ANSWER" | tail -n1 | clingo - postprocess.lp <(plasp ../../instances/PDDL/ipc-2000-elevator-m10-strips/domain.pddl ../../instances/PDDL/ipc-2000-elevator-m10-strips/problem-04-00.pddl) + +plasp ../../instances/PDDL/ipc-2000-elevator-m10-strips/domain.pddl ../../instances/PDDL/ipc-2000-elevator-m10-strips/problem-04-00.pddl | clingo - preprocess.lp strips-incremental.lp --outf=1 -c _parallel=2 | grep -A1 -e "ANSWER" | tail -n1 | clingo - postprocess.lp <(plasp ../../instances/PDDL/ipc-2000-elevator-m10-strips/domain.pddl ../../instances/PDDL/ipc-2000-elevator-m10-strips/problem-04-00.pddl) +``` diff --git a/encodings/strips/postprocess.lp b/encodings/strips/postprocess.lp new file mode 100644 index 0000000..3c24305 --- /dev/null +++ b/encodings/strips/postprocess.lp @@ -0,0 +1,58 @@ +% Convert a plan (possibly with parallel actions), given by atoms over occurs/2, +% to a sequential plan, expressed by atoms over sequence/2 + +time(T) :- occurs(A,T). +time :- time(T). + +:- goal(X,V), not initialState(X,V), not time. + +last(T2) :- time, T2 = #max{T1 : time(T1)}. + +offset(T2,M) :- time(T2), M = #count{A,T1 : occurs(A,T1), T1 < T2}. +finish(T,M+N) :- offset(T,M), N = #count{A : occurs(A,T)}. +index(T,M+1..N) :- offset(T,M), finish(T,N). + +postcondition(A,X,V) :- postcondition(A,E,X,V), occurs(A,T). +postcondition(A,X) :- postcondition(A,X,V). + +before(A1,A2,T) :- occurs(A1,T), occurs(A2,T), A1 != A2, + precondition(A1,X,V), postcondition(A2,X), not postcondition(A2,X,V). + +order(A1,A2,T) :- occurs(A1,T), occurs(A2,T), A1 < A2, A <= A1 : occurs(A,T), A < A2. +first(A2,T) :- occurs(A2,T), #false : order(A1,A2,T). + +undone(A,T,M) :- occurs(A,T), offset(T,M). +undone(A,T,N) :- undone(A,T,N-1), select(A1,T,N), A != A1, index(T,N+1). + +done(A,T,N) :- select(A,T,N). +done(A,T,N) :- done(A,T,N-1), index(T,N). + +:- finish(T,N), occurs(A,T), not done(A,T,N). + +hold(X,V,0) :- initialState(X,V). +hold(X,V,N) :- select(A,T,N), postcondition(A,X,V). +hold(X,V,N) :- select(A,T,N), hold(X,V,N-1), not postcondition(A,X). + +:- last(T), finish(T,N), goal(X,V), not hold(X,V,N). + +hold(X,N) :- hold(X,V,N). + +:- hold(X,N), #count{V : hold(X,V,N)} > 1. + +preconditions(A,T,N) :- undone(A,T,N), hold(X,V,N) : precondition(A,X,V). +applicable(A,T,N) :- preconditions(A,T,N), done(A1,T,N) : before(A1,A,T). + +inapplicable(A,T,N) :- done(A,T,N), index(T,N+1). +inapplicable(A,T,N) :- undone(A,T,N), precondition(A,X,V1), hold(X,V2,N), V1 != V2. +inapplicable(A,T,N) :- undone(A1,T,N), before(A1,A,T). + +continue(A2,T,N) :- order(A1,A2,T), inapplicable(A1,T,N), first(A1,T). +continue(A2,T,N) :- order(A1,A2,T), inapplicable(A1,T,N), continue(A1,T,N). + +select(A,T,N+1) :- applicable(A,T,N), first(A,T). +select(A,T,N+1) :- applicable(A,T,N), continue(A,T,N). + +% DISPLAY PART + +#show. +#show sequence(A,N) : select(A,T,N). diff --git a/encodings/strips/preprocess.lp b/encodings/strips/preprocess.lp new file mode 100644 index 0000000..bd60246 --- /dev/null +++ b/encodings/strips/preprocess.lp @@ -0,0 +1,48 @@ +% Constant '_closure' to (de)activate analysis of potentially relevant actions +% - value '1': forward chaining of effects w.r.t. initial variable values +% - value '2': backward regression of effects w.r.t. goal variable values +% - value '3': both forward chaining and backward regression of effects +% - otherwise: off + +#const _closure = 3. + +% Check feature requirements + +:- requires(feature(actionCosts)). +:- requires(feature(axiomRules)). +:- requires(feature(conditionalEffects)). + +% Basic redundancy check for actions + +postcondition(A,X,V) :- postcondition(A,E,X,V). + +has_condition(A,X,0) :- action(A), precondition(A,X,V). +has_condition(A,X,1) :- action(A), postcondition(A,X,V). + +inconsistent(A) :- has_condition(A,X,P), + #count{V : precondition(A,X,V), P = 0; + V : postcondition(A,X,V), P = 1} > 1. +consistent(A) :- action(A), not inconsistent(A). +irredundant(A) :- consistent(A), postcondition(A,X,V), not precondition(A,X,V). + +% Forward chaining of effects w.r.t. initial variable values + +feasible(X,V) :- initialState(X,V). +feasible(X,V) :- possible(A), postcondition(A,X,V). + +possible(A) :- irredundant(A), feasible(X,V) : precondition(A,X,V). +possible(A) :- irredundant(A), _closure != 1, _closure != 3. + +:- goal(X,V), not feasible(X,V). + +% Backward regression of effects w.r.t. goal variable values + +produce(X,V) :- goal(X,V), not initialState(X,V). +produce(X,V) :- active(A), precondition(A,X,V), not initialState(X,V). +produce(X,V) :- persist(X,V), active(A), has_condition(A,X,1), not postcondition(A,X,V). + +persist(X,V) :- goal(X,V), initialState(X,V). +persist(X,V) :- active(A), precondition(A,X,V), initialState(X,V). + +active(A) :- possible(A), postcondition(A,X,V), produce(X,V). +active(A) :- possible(A), _closure != 2, _closure != 3. diff --git a/encodings/strips/redundancy.lp b/encodings/strips/redundancy.lp new file mode 100644 index 0000000..ef67f92 --- /dev/null +++ b/encodings/strips/redundancy.lp @@ -0,0 +1,33 @@ +% Additional rules for enforcing the inclusion of parallel actions in plans, +% whenever such 'redundant' actions are compatible with states and other actions + +compatible(A,A1) :- active(A), active(A1), A != A1, _parallel = 2, + not diverge(A,A1), not diverge(A1,A). +compatible(A) :- compatible(A,A1). + +disable(A,A1,A2) :- disable(A1,A2), compatible(A,A1), compatible(A,A2). +disabled(A,A2) :- disable(A,A1,A2). +disabled(A,A2) :- disable(A,A2). + +#program step(t). + +defeated(A,t) :- active(A), postcondition(A,X,V), fluent(X), not holds(X,V,t), + _parallel = 1 : _parallel != 2. + +defeated(A,t) :- _parallel = 1, active(A), precondition(A,X,V), not holds(X,V,t-1). +defeated(A,t) :- _parallel = 1, active(A), precondition(A,X,V), not holds(X,V,t). +defeated(A,t) :- _parallel = 1, active(A), postcondition(A,X,V), not precondition(A,X,V), + single(X,t). + +proceed(A,X,V,t) :- compatible(A), holds(X,V,t-1), scope(X,V). +proceed(A,X,V,t) :- compatible(A,A1), occurs(A1,t), perform(A,A1,t), + postcondition(A1,X,V), scope(X,V), not precondition(A1,X,V). + +perform(A,A1,t) :- disabled(A,A1), not occurs(A1,t). +perform(A,A1,t) :- compatible(A,A1), + proceed(A,X,V,t) : precondition(A1,X,V); perform(A,A2,t) : disable(A,A1,A2). + +defeated(A,t) :- compatible(A), precondition(A,X,V), not proceed(A,X,V,t). +defeated(A,t) :- compatible(A), disable(A,A2), not perform(A,A2,t). + +:- active(A), not occurs(A,t), not defeated(A,t), _parallel = 1 : _parallel != 2. diff --git a/encodings/strips/strips-incremental.lp b/encodings/strips/strips-incremental.lp new file mode 100644 index 0000000..8f26060 --- /dev/null +++ b/encodings/strips/strips-incremental.lp @@ -0,0 +1,104 @@ +% Constant '_parallel' to enable parallel actions +% - value '1': "forall" parallel actions that can be arranged in any sequence +% - value '2': "exists" parallel actions that can be arranged in some sequence +% - otherwise: sequential actions + +#const _parallel = 0. + +#include . + +% BASE PROGRAM + +% Define auxiliary predicates for actions w.r.t. parallel mode + +diverge(A1,A2,X) :- active(A1), active(A2), A1 < A2, postcondition(A1,X,V), + has_condition(A2,X,1), not postcondition(A2,X,V), + _parallel = 1 : _parallel != 2. +diverge(A1,A2) :- diverge(A1,A2,X). + +exclude(A1,A2) :- diverge(A1,A2), precondition(A1,X,V), _parallel = 1, + has_condition(A2,X,0), not precondition(A2,X,V). + +disable(A1,A2) :- active(A1), active(A2), A1 != A2, postcondition(A1,X,V), + has_condition(A2,X,0), not precondition(A2,X,V), + _parallel = 2, not diverge(A1,A2), not diverge(A2,A1). + +scope(X,V) :- active(A), precondition(A,X,V), _parallel = 2. + +% Define relevant fluents w.r.t. parallel mode + +fluent(X,V) :- produce(X,V). +fluent(X,V) :- persist(X,V). +fluent(X,V) :- initialState(X,V), fluent(X). +fluent(X,V) :- active(A), postcondition(A,X,V), fluent(X). +fluent(X) :- fluent(X,V). +fluent(X) :- diverge(A1,A2,X), not exclude(A1,A2). + +% Define unsubsumed mutexes + +mutex(G,X) :- mutexGroup(G), contains(G,X,V), fluent(X,V). +mutex(G) :- mutexGroup(G), #count{X : mutex(G,X)} > 1. + +% Define initial state + +holds(X,V,0) :- initialState(X,V), fluent(X). + +:- fluent(X), #count{V : holds(X,V,0)} > 1. +:- mutex(G), #count{X,V : holds(X,V,0), contains(G,X,V)} > 1. + +% STEP PROGRAM + +#program step(t). + +% Generate successor state + +1 {holds(X,V,t) : fluent(X,V)} 1 :- fluent(X). + +:- mutex(G), #count{X,V : holds(X,V,t), contains(G,X,V)} > 1. + +change(X,t) :- holds(X,V,t-1), not holds(X,V,t). + +% Generate actions + +1 {occurs(A,t) : active(A)}. + +:- occurs(A,t), postcondition(A,X,V), fluent(X), not holds(X,V,t). + +effect(X,t) :- occurs(A,t), postcondition(A,X,V), fluent(X), not precondition(A,X,V). + +:- change(X,t), not effect(X,t). + +% Checks w.r.t. parallel mode + +:- _parallel != 1, _parallel != 2, #count{A : occurs(A,t)} > 1. + +:- _parallel != 2, occurs(A,t), precondition(A,X,V), not holds(X,V,t-1). + +:- _parallel = 1, occurs(A,t), precondition(A,X,V), not has_condition(A,X,1), not holds(X,V,t). + +single(X,t) :- occurs(A,t), precondition(A,X,V), _parallel = 1, + has_condition(A,X,1), not postcondition(A,X,V). + +:- single(X,t), #count{A : occurs(A,t), postcondition(A,X,V), not precondition(A,X,V)} > 1. + +proceed(X,V,t) :- holds(X,V,t-1), scope(X,V). +proceed(X,V,t) :- occurs(A,t), postcondition(A,X,V), scope(X,V), not precondition(A,X,V), + perform(A,t). + +perform(A1,t) :- active(A1), _parallel = 2, not occurs(A1,t). +perform(A1,t) :- active(A1), _parallel = 2, + proceed(X,V,t) : precondition(A1,X,V); perform(A2,t) : disable(A1,A2). + +:- _parallel = 2, active(A), not perform(A,t). + +% CHECK PROGRAM + +#program check(t). + +% Check goal conditions + +:- query(t), goal(X,V), not holds(X,V,t). + +% DISPLAY PART + +#show occurs/2. diff --git a/include/plasp/Language.h b/include/plasp/Language.h index 7769a0b..c5e15a9 100644 --- a/include/plasp/Language.h +++ b/include/plasp/Language.h @@ -1,7 +1,7 @@ #ifndef __PLASP__LANGUAGE_H #define __PLASP__LANGUAGE_H -#include +#include namespace plasp { @@ -18,6 +18,7 @@ class Language enum class Type { Unknown, + Automatic, PDDL, SAS }; diff --git a/include/plasp/LanguageDetection.h b/include/plasp/LanguageDetection.h index dc7ccb2..481ff5d 100644 --- a/include/plasp/LanguageDetection.h +++ b/include/plasp/LanguageDetection.h @@ -2,7 +2,7 @@ #define __PLASP__LANGUAGE_DETECTION_H #include -#include +#include namespace plasp { @@ -13,7 +13,7 @@ namespace plasp // //////////////////////////////////////////////////////////////////////////////////////////////////// -Language::Type detectLanguage(utils::Parser &parser) +Language::Type detectLanguage(input::Parser &parser) { parser.skipWhiteSpace(); diff --git a/include/plasp/utils/StreamCoordinate.h b/include/plasp/input/Location.h similarity index 52% rename from include/plasp/utils/StreamCoordinate.h rename to include/plasp/input/Location.h index 341063a..9c17789 100644 --- a/include/plasp/utils/StreamCoordinate.h +++ b/include/plasp/input/Location.h @@ -1,24 +1,29 @@ -#ifndef __PLASP__UTILS__STREAM_COORDINATE_H -#define __PLASP__UTILS__STREAM_COORDINATE_H +#ifndef __PLASP__INPUT__LOCATION_H +#define __PLASP__INPUT__LOCATION_H -#include +#include namespace plasp { -namespace utils +namespace input { //////////////////////////////////////////////////////////////////////////////////////////////////// // -// StreamCoordinate +// Location // //////////////////////////////////////////////////////////////////////////////////////////////////// -struct StreamCoordinate +struct Location { - std::string sectionName; - size_t row; - size_t column; + const char *sectionStart = nullptr; + const char *sectionEnd = nullptr; + + std::size_t rowStart = -1; + std::size_t rowEnd = -1; + + std::size_t columnStart = -1; + std::size_t columnEnd = -1; }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/utils/Parser.h b/include/plasp/input/Parser.h similarity index 96% rename from include/plasp/utils/Parser.h rename to include/plasp/input/Parser.h index 266a0ed..fc0c096 100644 --- a/include/plasp/utils/Parser.h +++ b/include/plasp/input/Parser.h @@ -1,5 +1,5 @@ -#ifndef __PLASP__UTILS__PARSER_H -#define __PLASP__UTILS__PARSER_H +#ifndef __PLASP__INPUT__PARSER_H +#define __PLASP__INPUT__PARSER_H #include #include @@ -8,14 +8,13 @@ #include -#include -#include -#include -#include +#include +#include +#include namespace plasp { -namespace utils +namespace input { template @@ -199,7 +198,7 @@ void Parser::expect(const Type &expectedValue) std::stringstream message; message << "unexpected value, expected “" << expectedValue << "”"; - throw ParserException(coordinate(), message.str()); + throw ParserException(location(), message.str()); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -402,7 +401,7 @@ uint64_t Parser::parseIntegerBody() check(); if (!std::isdigit(currentCharacter())) - throw ParserException(coordinate(), "could not parse integer value"); + throw ParserException(location(), "could not parse integer value"); uint64_t value = 0; @@ -444,7 +443,7 @@ uint64_t Parser::parseImpl(Tag) skipWhiteSpace(); if (currentCharacter() == '-') - throw ParserException(coordinate(), "expected unsigned integer, got signed one"); + throw ParserException(location(), "expected unsigned integer, got signed one"); return parseIntegerBody(); } @@ -478,7 +477,7 @@ bool Parser::parseImpl(Tag) if (testAndSkip('1')) return true; - throw ParserException(coordinate(), "could not parse Boolean value"); + throw ParserException(location(), "could not parse Boolean value"); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/input/ParserException.h b/include/plasp/input/ParserException.h new file mode 100644 index 0000000..81a0ea6 --- /dev/null +++ b/include/plasp/input/ParserException.h @@ -0,0 +1,72 @@ +#ifndef __PLASP__INPUT__PARSER_EXCEPTION_H +#define __PLASP__INPUT__PARSER_EXCEPTION_H + +#include +#include + +#include + +namespace plasp +{ +namespace input +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// ParserException +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class ParserException: public std::exception +{ + public: + explicit ParserException(const input::Location &location) + : ParserException(location, "unspecified parser error") + { + } + + explicit ParserException(const input::Location &location, const char *message) + : ParserException(location, static_cast(message)) + { + } + + explicit ParserException(const input::Location &location, const std::string &message) + : m_location{location}, + m_message{message}, + // TODO: refactor + m_plainMessage{std::string(m_location.sectionStart) + ":" + std::to_string(m_location.rowStart) + + ":" + std::to_string(m_location.columnStart) + " " + m_message} + { + } + + ~ParserException() throw() + { + } + + const char *what() const throw() + { + return m_plainMessage.c_str(); + } + + const input::Location &location() const + { + return m_location; + } + + const std::string &message() const + { + return m_message; + } + + private: + input::Location m_location; + std::string m_message; + std::string m_plainMessage; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/include/plasp/utils/ParserPolicy.h b/include/plasp/input/ParserPolicy.h similarity index 92% rename from include/plasp/utils/ParserPolicy.h rename to include/plasp/input/ParserPolicy.h index 220516d..8b829c5 100644 --- a/include/plasp/utils/ParserPolicy.h +++ b/include/plasp/input/ParserPolicy.h @@ -1,11 +1,11 @@ -#ifndef __PLASP__UTILS__PARSER_POLICY_H -#define __PLASP__UTILS__PARSER_POLICY_H +#ifndef __PLASP__INPUT__PARSER_POLICY_H +#define __PLASP__INPUT__PARSER_POLICY_H #include namespace plasp { -namespace utils +namespace input { //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/utils/Stream.h b/include/plasp/input/Stream.h similarity index 87% rename from include/plasp/utils/Stream.h rename to include/plasp/input/Stream.h index ef6f780..f52e20c 100644 --- a/include/plasp/utils/Stream.h +++ b/include/plasp/input/Stream.h @@ -1,5 +1,5 @@ -#ifndef __PLASP__UTILS__STREAM_H -#define __PLASP__UTILS__STREAM_H +#ifndef __PLASP__INPUT__STREAM_H +#define __PLASP__INPUT__STREAM_H #include #include @@ -8,12 +8,11 @@ #include -#include -#include +#include namespace plasp { -namespace utils +namespace input { //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -62,7 +61,7 @@ class Stream void reset(); void seek(Position position); Position position() const; - StreamCoordinate coordinate() const; + Location location() const; char currentCharacter() const; void advance(); diff --git a/include/plasp/output/ColorStream.h b/include/plasp/output/ColorStream.h new file mode 100644 index 0000000..feecaa8 --- /dev/null +++ b/include/plasp/output/ColorStream.h @@ -0,0 +1,294 @@ +#ifndef __PLASP__OUTPUT__COLOR_STREAM_H +#define __PLASP__OUTPUT__COLOR_STREAM_H + +#include +#include + +namespace plasp +{ +namespace output +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// ColorStream +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class ColorStream +{ + public: + enum class ColorPolicy + { + Never, + Auto, + Always + }; + + private: + using CharacterType = std::ostream::char_type; + using TraitsType = std::ostream::traits_type; + + public: + ColorStream(std::ostream &stream) + : m_stream{stream}, + m_colorPolicy{ColorPolicy::Auto} + { + } + + void setColorPolicy(ColorPolicy colorPolicy) + { + m_colorPolicy = colorPolicy; + } + + bool supportsColor() const + { + if (m_colorPolicy == ColorPolicy::Never) + return false; + + if (m_colorPolicy == ColorPolicy::Always) + return true; + + if (&m_stream == &std::cout) + return isatty(fileno(stdout)); + + if (&m_stream == &std::cerr) + return isatty(fileno(stderr)); + + return false; + } + + std::ostream &stream() + { + return m_stream; + } + + inline ColorStream &operator<<(short value); + inline ColorStream &operator<<(unsigned short value); + inline ColorStream &operator<<(int value); + inline ColorStream &operator<<(unsigned int value); + inline ColorStream &operator<<(long value); + inline ColorStream &operator<<(unsigned long value); + inline ColorStream &operator<<(long long value); + inline ColorStream &operator<<(unsigned long long value); + inline ColorStream &operator<<(float value); + inline ColorStream &operator<<(double value); + inline ColorStream &operator<<(long double value); + inline ColorStream &operator<<(bool value); + inline ColorStream &operator<<(const void *value); + inline ColorStream &operator<<(const char *value); + inline ColorStream &operator<<(const signed char *value); + inline ColorStream &operator<<(const unsigned char *value); + inline ColorStream &operator<<(std::basic_streambuf *sb); + inline ColorStream &operator<<(std::ios_base &(*func)(std::ios_base &)); + inline ColorStream &operator<<(std::basic_ios &(*func)(std::basic_ios &)); + inline ColorStream &operator<<(std::basic_ostream &(*func)(std::basic_ostream &)); + + inline ColorStream &operator<<(char value); + inline ColorStream &operator<<(signed char value); + inline ColorStream &operator<<(unsigned char value); + + private: + std::ostream &m_stream; + ColorPolicy m_colorPolicy; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(short value) +{ + m_stream << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(unsigned short value) +{ + m_stream << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(int value) +{ + m_stream << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(unsigned int value) +{ + m_stream << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(long value) +{ + m_stream << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(unsigned long value) +{ + m_stream << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(long long value) +{ + m_stream << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(unsigned long long value) +{ + m_stream << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(float value) +{ + m_stream << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(double value) +{ + m_stream << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(long double value) +{ + m_stream << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(bool value) +{ + m_stream << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(const void *value) +{ + m_stream << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(const char *value) +{ + m_stream << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(const signed char *value) +{ + m_stream << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(const unsigned char *value) +{ + m_stream << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(std::basic_streambuf* sb) +{ + m_stream << sb; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(std::ios_base &(*func)(std::ios_base &)) +{ + m_stream << func; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(std::basic_ios &(*func)(std::basic_ios &)) +{ + m_stream << func; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(std::basic_ostream &(*func)(std::basic_ostream &)) +{ + m_stream << func; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +inline ColorStream &operator<<(ColorStream &colorStream, const std::basic_string &string) +{ + colorStream.stream() << string; + return colorStream; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(char value) +{ + m_stream << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(signed char value) +{ + m_stream << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &ColorStream::operator<<(unsigned char value) +{ + m_stream << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/include/plasp/utils/Formatting.h b/include/plasp/output/Formatting.h similarity index 51% rename from include/plasp/utils/Formatting.h rename to include/plasp/output/Formatting.h index 631f36a..147809c 100644 --- a/include/plasp/utils/Formatting.h +++ b/include/plasp/output/Formatting.h @@ -1,13 +1,13 @@ -#ifndef __PLASP__UTILS__FORMATTING_H -#define __PLASP__UTILS__FORMATTING_H +#ifndef __PLASP__OUTPUT__FORMATTING_H +#define __PLASP__OUTPUT__FORMATTING_H #include -#include +#include namespace plasp { -namespace utils +namespace output { //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -18,21 +18,30 @@ namespace utils enum class Color { - Black = 0, - Red = 1, - Green = 2, - Yellow = 3, - Blue = 4, - Magenta = 5, - Cyan = 6, - White = 7 + Default = 39, + Black = 30, + Red = 31, + Green = 32, + Yellow = 33, + Blue = 34, + Magenta = 35, + Cyan = 36, + LightGray = 37, + DarkGray = 90, + LightRed = 91, + LightGreen = 92, + LightYellow = 93, + LightBlue = 94, + LightMagenta = 95, + LightCyan = 96, + White = 97 }; //////////////////////////////////////////////////////////////////////////////////////////////////// enum class FontWeight { - Normal = 0, + Normal = 21, Bold = 1 }; @@ -40,25 +49,19 @@ enum class FontWeight struct Format { - Format(Color color, FontWeight fontWeight = FontWeight::Normal) - : m_color{color}, - m_fontWeight{fontWeight} - { - } - - Color m_color; - FontWeight m_fontWeight; + Color color = Color::Default; + FontWeight fontWeight = FontWeight::Normal; }; //////////////////////////////////////////////////////////////////////////////////////////////////// -inline LogStream &operator<<(LogStream &stream, const Format &format) +inline ColorStream &operator<<(ColorStream &stream, const Format &format) { if (!stream.supportsColor()) return stream; - const auto fontWeightCode = static_cast(format.m_fontWeight); - const auto colorCode = 30 + static_cast(format.m_color); + const auto fontWeightCode = static_cast(format.fontWeight); + const auto colorCode = static_cast(format.color); return (stream << "\033[" << fontWeightCode << ";" << colorCode << "m"); } @@ -71,7 +74,7 @@ struct ResetFormat //////////////////////////////////////////////////////////////////////////////////////////////////// -inline LogStream &operator<<(LogStream &stream, const ResetFormat &) +inline ColorStream &operator<<(ColorStream &stream, const ResetFormat &) { if (!stream.supportsColor()) return stream; @@ -81,196 +84,224 @@ inline LogStream &operator<<(LogStream &stream, const ResetFormat &) //////////////////////////////////////////////////////////////////////////////////////////////////// -struct Token +struct Function { - Token(const std::string &name) - : name(name) + Function(const char *name) + : name{name} { - } + }; - const std::string &name; + const char *name; }; //////////////////////////////////////////////////////////////////////////////////////////////////// -struct RuleName: public Token -{ - RuleName(const std::string &name) - : Token(name) - { - } -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -inline LogStream &operator<<(LogStream &stream, const RuleName &keyword) +inline ColorStream &operator<<(ColorStream &stream, const Function &function) { return (stream - << utils::Format(utils::Color::White, utils::FontWeight::Bold) + << Format({Color::White, FontWeight::Normal}) + << function.name + << ResetFormat()); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct Keyword +{ + Keyword(const char *name) + : name{name} + { + }; + + const char *name; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +inline ColorStream &operator<<(ColorStream &stream, const Keyword &keyword) +{ + return (stream + << Format({Color::Blue, FontWeight::Normal}) << keyword.name - << utils::ResetFormat()); + << ResetFormat()); } //////////////////////////////////////////////////////////////////////////////////////////////////// -struct Keyword: public Token +struct Operator { - Keyword(const std::string &name) - : Token(name) + Operator(const char *name) + : name{name} { - } + }; + + const char *name; }; //////////////////////////////////////////////////////////////////////////////////////////////////// -inline LogStream &operator<<(LogStream &stream, const Keyword &keyword) +inline ColorStream &operator<<(ColorStream &stream, const Operator &operator_) { - return (stream - << utils::Format(utils::Color::Blue, utils::FontWeight::Normal) - << keyword.name - << utils::ResetFormat()); -} -//////////////////////////////////////////////////////////////////////////////////////////////////// - -struct Number: public Token -{ - Number(const std::string &name) - : Token(name) - { - } -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -inline LogStream &operator<<(LogStream &stream, const Number &number) -{ - return (stream - << utils::Format(utils::Color::Yellow, utils::FontWeight::Normal) - << number.name - << utils::ResetFormat()); + return (stream << operator_.name); } //////////////////////////////////////////////////////////////////////////////////////////////////// -struct Variable: public Token +template +struct Number { - Variable(const std::string &name) - : Token(name) + Number(T value) + : value{value} { - } + }; + + T value; }; //////////////////////////////////////////////////////////////////////////////////////////////////// -inline LogStream &operator<<(LogStream &stream, const Variable &variable) +template +inline ColorStream &operator<<(ColorStream &stream, const Number &number) { return (stream - << utils::Format(utils::Color::Green, utils::FontWeight::Bold) + << Format({Color::Yellow, FontWeight::Normal}) + << number.value + << ResetFormat()); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct Variable +{ + Variable(const char *name) + : name{name} + { + }; + + const char *name; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +inline ColorStream &operator<<(ColorStream &stream, const Variable &variable) +{ + return (stream + << Format({Color::Green, FontWeight::Bold}) << variable.name - << utils::ResetFormat()); + << ResetFormat()); } //////////////////////////////////////////////////////////////////////////////////////////////////// -struct String: public Token +struct String { - String(const std::string &name) - : Token(name) + String(const char *content) + : content{content} { - } + }; + + const char *content; }; //////////////////////////////////////////////////////////////////////////////////////////////////// -inline LogStream &operator<<(LogStream &stream, const String &string) +inline ColorStream &operator<<(ColorStream &stream, const String &string) { return (stream - << utils::Format(utils::Color::Green, utils::FontWeight::Normal) - << "\"" << string.name << "\"" - << utils::ResetFormat()); + << Format({Color::Green, FontWeight::Normal}) + << "\"" << string.content << "\"" + << ResetFormat()); } //////////////////////////////////////////////////////////////////////////////////////////////////// -struct Boolean: public Token +struct Boolean { - Boolean(const std::string &name) - : Token(name) + Boolean(const char *value) + : value{value} { - } + }; + + const char *value; }; //////////////////////////////////////////////////////////////////////////////////////////////////// -inline LogStream &operator<<(LogStream &stream, const Boolean &string) +inline ColorStream &operator<<(ColorStream &stream, const Boolean &boolean) { return (stream - << utils::Format(utils::Color::Red, utils::FontWeight::Normal) - << string.name - << utils::ResetFormat()); + << Format({Color::Red, FontWeight::Normal}) + << boolean.value + << ResetFormat()); } //////////////////////////////////////////////////////////////////////////////////////////////////// -struct Reserved: public Token +struct Reserved { - Reserved(const std::string &name) - : Token(name) + Reserved(const char *name) + : name{name} { - } + }; + + const char *name; }; //////////////////////////////////////////////////////////////////////////////////////////////////// -inline LogStream &operator<<(LogStream &stream, const Reserved &string) +inline ColorStream &operator<<(ColorStream &stream, const Reserved &reserved) { return (stream - << utils::Format(utils::Color::White, utils::FontWeight::Normal) - << string.name - << utils::ResetFormat()); + << Format({Color::White, FontWeight::Normal}) + << reserved.name + << ResetFormat()); } //////////////////////////////////////////////////////////////////////////////////////////////////// -struct Heading1: public Token +struct Heading1 { - Heading1(const std::string &name) - : Token(name) + Heading1(const char *content) + : content{content} { - } + }; + + const char *content; }; //////////////////////////////////////////////////////////////////////////////////////////////////// -inline LogStream &operator<<(LogStream &stream, const Heading1 &heading1) +inline ColorStream &operator<<(ColorStream &stream, const Heading1 &heading1) { return (stream - << utils::Format(utils::Color::Blue, utils::FontWeight::Bold) + << Format({Color::Blue, FontWeight::Bold}) << "%---------------------------------------" << std::endl - << "% " << heading1.name << std::endl + << "% " << heading1.content << std::endl << "%---------------------------------------" - << utils::ResetFormat() + << ResetFormat() << std::endl); } //////////////////////////////////////////////////////////////////////////////////////////////////// -struct Heading2: public Token +struct Heading2 { - Heading2(const std::string &name) - : Token(name) + Heading2(const char *content) + : content{content} { - } + }; + + const char *content; }; //////////////////////////////////////////////////////////////////////////////////////////////////// -inline LogStream &operator<<(LogStream &stream, const Heading2 &heading2) +inline ColorStream &operator<<(ColorStream &stream, const Heading2 &heading2) { return (stream - << utils::Format(utils::Color::Blue, utils::FontWeight::Bold) - << "% " << heading2.name - << utils::ResetFormat()); + << Format({Color::Blue, FontWeight::Bold}) + << "% " << heading2.content + << ResetFormat()); } diff --git a/include/plasp/output/Logger.h b/include/plasp/output/Logger.h new file mode 100644 index 0000000..8624426 --- /dev/null +++ b/include/plasp/output/Logger.h @@ -0,0 +1,57 @@ +#ifndef __PLASP__OUTPUT__LOGGER_H +#define __PLASP__OUTPUT__LOGGER_H + +#include + +#include +#include +#include + +namespace plasp +{ +namespace output +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Logger +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class Logger +{ + public: + explicit Logger(); + explicit Logger(ColorStream &&outputStream); + explicit Logger(ColorStream &&outputStream, ColorStream &&errorStream); + Logger(Logger &&other); + Logger &operator=(Logger &&other); + + ColorStream &outputStream(); + ColorStream &errorStream(); + + // The priority from which on messages should be printed + void setLogPriority(Priority logPriority); + // Messages with this priority (or higher) will terminate the program’s execution + void setAbortPriority(Priority abortPriority); + void setColorPolicy(ColorStream::ColorPolicy colorPolicy); + + void log(Priority priority, const char *message); + void log(Priority priority, const std::string &message); + void log(Priority priority, const input::Location &location, const char *message); + void log(Priority priority, const input::Location &location, const std::string &message); + + private: + ColorStream m_outputStream; + ColorStream m_errorStream; + + Priority m_logPriority; + Priority m_abortPriority; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/include/plasp/output/Priority.h b/include/plasp/output/Priority.h new file mode 100644 index 0000000..ff1baed --- /dev/null +++ b/include/plasp/output/Priority.h @@ -0,0 +1,66 @@ +#ifndef __PLASP__OUTPUT__PRIORITY_H +#define __PLASP__OUTPUT__PRIORITY_H + +#include +#include + +namespace plasp +{ +namespace output +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Priority +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +enum class Priority +{ + Debug, + Info, + Warning, + Error +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +inline constexpr const char *priorityName(Priority priority) +{ + switch (priority) + { + case Priority::Debug: + return "debug"; + case Priority::Info: + return "info"; + case Priority::Warning: + return "warning"; + case Priority::Error: + return "error"; + } + + return "unknown"; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +inline Priority priorityFromName(const char *priorityName) +{ + if (std::strcmp(priorityName, "debug") == 0) + return Priority::Debug; + if (std::strcmp(priorityName, "info") == 0) + return Priority::Info; + if (std::strcmp(priorityName, "warning") == 0) + return Priority::Warning; + if (std::strcmp(priorityName, "error") == 0) + return Priority::Error; + + throw std::runtime_error("unknown log priority"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/include/plasp/utils/TranslatorException.h b/include/plasp/output/TranslatorException.h similarity index 89% rename from include/plasp/utils/TranslatorException.h rename to include/plasp/output/TranslatorException.h index 73e3239..46cf4db 100644 --- a/include/plasp/utils/TranslatorException.h +++ b/include/plasp/output/TranslatorException.h @@ -1,12 +1,12 @@ -#ifndef __PLASP__UTILS__TRANSLATOR_EXCEPTION_H -#define __PLASP__UTILS__TRANSLATOR_EXCEPTION_H +#ifndef __PLASP__OUTPUT__TRANSLATOR_EXCEPTION_H +#define __PLASP__OUTPUT__TRANSLATOR_EXCEPTION_H #include #include namespace plasp { -namespace utils +namespace output { //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/pddl/Action.h b/include/plasp/pddl/Action.h index 35cef85..c1ed856 100644 --- a/include/plasp/pddl/Action.h +++ b/include/plasp/pddl/Action.h @@ -3,9 +3,9 @@ #include +#include #include #include -#include namespace plasp { diff --git a/include/plasp/pddl/Context.h b/include/plasp/pddl/Context.h index 8844c91..0c6f2eb 100644 --- a/include/plasp/pddl/Context.h +++ b/include/plasp/pddl/Context.h @@ -5,8 +5,8 @@ #include #include +#include #include -#include namespace plasp { @@ -25,19 +25,9 @@ class Context Context() = default; ~Context() = default; - explicit Context(Parser &&otherParser) - : parser{std::move(otherParser)} - { - } - - explicit Context(utils::Logger &&otherLogger) - : logger{std::move(otherLogger)} - { - } - - explicit Context(Parser &&otherParser, utils::Logger &&otherLogger) + explicit Context(Parser &&otherParser, output::Logger &otherLogger) : parser{std::move(otherParser)}, - logger{std::move(otherLogger)} + logger(otherLogger) { } @@ -46,17 +36,11 @@ class Context Context(Context &&other) : parser(std::move(other.parser)), - logger(std::move(other.logger)) + logger(other.logger) { } - Context &operator=(Context &&other) - { - parser = std::move(other.parser); - logger = std::move(other.logger); - - return *this; - } + Context &operator=(Context &&other) = delete; constexpr static const char *auxiliaryPrefix() { @@ -64,7 +48,7 @@ class Context } Parser parser; - utils::Logger logger; + output::Logger &logger; }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/pddl/Description.h b/include/plasp/pddl/Description.h index 87e5740..2483bf2 100644 --- a/include/plasp/pddl/Description.h +++ b/include/plasp/pddl/Description.h @@ -5,7 +5,7 @@ #include #include -#include +#include namespace plasp { @@ -21,10 +21,10 @@ namespace pddl class Description { public: - static Description fromContext(Context &&context); - static Description fromStream(std::istream &istream); - static Description fromFile(const std::string &path); - static Description fromFiles(const std::vector &paths); + static Description fromContext(Context &context); + static Description fromStream(std::istream &istream, Context &context); + static Description fromFile(const std::string &path, Context &context); + static Description fromFiles(const std::vector &paths, Context &context); public: Context &context(); @@ -38,18 +38,18 @@ class Description void normalize(); private: - Description(); + Description(Context &context); void parse(); void findSections(); void checkConsistency(); - Context m_context; + Context &m_context; - utils::Stream::Position m_domainPosition; + input::Stream::Position m_domainPosition; std::unique_ptr m_domain; - utils::Stream::Position m_problemPosition; + input::Stream::Position m_problemPosition; std::unique_ptr m_problem; }; diff --git a/include/plasp/pddl/Domain.h b/include/plasp/pddl/Domain.h index d908699..c13741a 100644 --- a/include/plasp/pddl/Domain.h +++ b/include/plasp/pddl/Domain.h @@ -75,19 +75,19 @@ class Domain std::string m_name; - utils::Stream::Position m_requirementsPosition; + input::Stream::Position m_requirementsPosition; Requirements m_requirements; - utils::Stream::Position m_typesPosition; + input::Stream::Position m_typesPosition; expressions::PrimitiveTypes m_types; - utils::Stream::Position m_constantsPosition; + input::Stream::Position m_constantsPosition; expressions::Constants m_constants; - utils::Stream::Position m_predicatesPosition; + input::Stream::Position m_predicatesPosition; expressions::PredicateDeclarations m_predicates; - std::vector m_actionPositions; + std::vector m_actionPositions; std::vector> m_actions; expressions::DerivedPredicates m_derivedPredicates; diff --git a/include/plasp/pddl/Expression.h b/include/plasp/pddl/Expression.h index aeb1d4e..85a8c89 100644 --- a/include/plasp/pddl/Expression.h +++ b/include/plasp/pddl/Expression.h @@ -5,7 +5,7 @@ #include -#include +#include namespace plasp { diff --git a/include/plasp/pddl/Parser.h b/include/plasp/pddl/Parser.h index acb0c87..4badd0e 100644 --- a/include/plasp/pddl/Parser.h +++ b/include/plasp/pddl/Parser.h @@ -1,7 +1,7 @@ #ifndef __PLASP__PDDL__PARSER_H #define __PLASP__PDDL__PARSER_H -#include +#include namespace plasp { @@ -44,7 +44,7 @@ class PDDLParserPolicy //////////////////////////////////////////////////////////////////////////////////////////////////// -using Parser = utils::Parser; +using Parser = input::Parser; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/pddl/Problem.h b/include/plasp/pddl/Problem.h index d21b40f..05f53d3 100644 --- a/include/plasp/pddl/Problem.h +++ b/include/plasp/pddl/Problem.h @@ -64,18 +64,18 @@ class Problem std::string m_name; - utils::Stream::Position m_domainPosition; + input::Stream::Position m_domainPosition; - utils::Stream::Position m_requirementsPosition; + input::Stream::Position m_requirementsPosition; Requirements m_requirements; - utils::Stream::Position m_objectsPosition; + input::Stream::Position m_objectsPosition; expressions::Constants m_objects; - utils::Stream::Position m_initialStatePosition; + input::Stream::Position m_initialStatePosition; std::unique_ptr m_initialState; - utils::Stream::Position m_goalPosition; + input::Stream::Position m_goalPosition; ExpressionPointer m_goal; }; diff --git a/include/plasp/pddl/TranslatorASP.h b/include/plasp/pddl/TranslatorASP.h index da33689..aac4843 100644 --- a/include/plasp/pddl/TranslatorASP.h +++ b/include/plasp/pddl/TranslatorASP.h @@ -19,7 +19,7 @@ namespace pddl class TranslatorASP { public: - explicit TranslatorASP(Description &description, utils::LogStream &outputStream); + explicit TranslatorASP(Description &description, output::ColorStream &outputStream); void translate() const; @@ -40,7 +40,7 @@ class TranslatorASP void translatePredicate(const expressions::Predicate &predicate) const; Description &m_description; - utils::LogStream &m_outputStream; + output::ColorStream &m_outputStream; }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/pddl/expressions/Constant.h b/include/plasp/pddl/expressions/Constant.h index 26b3461..89a0284 100644 --- a/include/plasp/pddl/expressions/Constant.h +++ b/include/plasp/pddl/expressions/Constant.h @@ -2,8 +2,6 @@ #define __PLASP__PDDL__EXPRESSIONS__CONSTANT_H #include -#include -#include namespace plasp { diff --git a/include/plasp/pddl/expressions/NAry.h b/include/plasp/pddl/expressions/NAry.h index db6420a..9c26278 100644 --- a/include/plasp/pddl/expressions/NAry.h +++ b/include/plasp/pddl/expressions/NAry.h @@ -79,7 +79,7 @@ boost::intrusive_ptr NAry::parse(Context &context, } if (expression->m_arguments.empty()) - context.logger.logWarning(parser.coordinate(), "“" + Derived::Identifier + "” expressions should not be empty"); + context.logger.log(output::Priority::Warning, parser.location(), "“" + Derived::Identifier + "” expressions should not be empty"); parser.expect(")"); diff --git a/include/plasp/pddl/expressions/PrimitiveType.h b/include/plasp/pddl/expressions/PrimitiveType.h index 394bb87..f47817f 100644 --- a/include/plasp/pddl/expressions/PrimitiveType.h +++ b/include/plasp/pddl/expressions/PrimitiveType.h @@ -2,7 +2,6 @@ #define __PLASP__PDDL__EXPRESSIONS__PRIMITIVE_TYPE_H #include -#include namespace plasp { diff --git a/include/plasp/sas/AssignedVariable.h b/include/plasp/sas/AssignedVariable.h index 7dc438b..5eef7e3 100644 --- a/include/plasp/sas/AssignedVariable.h +++ b/include/plasp/sas/AssignedVariable.h @@ -4,9 +4,9 @@ #include #include +#include #include #include -#include namespace plasp { @@ -27,8 +27,8 @@ using AssignedVariables = std::vector; class AssignedVariable { public: - static AssignedVariable fromSAS(utils::Parser<> &parser, const Variables &variables); - static AssignedVariable fromSAS(utils::Parser<> &parser, const Variable &variable); + static AssignedVariable fromSAS(input::Parser<> &parser, const Variables &variables); + static AssignedVariable fromSAS(input::Parser<> &parser, const Variable &variable); public: explicit AssignedVariable(const Variable &variable, const Value &value); diff --git a/include/plasp/sas/AxiomRule.h b/include/plasp/sas/AxiomRule.h index 88fa1db..32875b2 100644 --- a/include/plasp/sas/AxiomRule.h +++ b/include/plasp/sas/AxiomRule.h @@ -3,9 +3,9 @@ #include +#include #include #include -#include namespace plasp { @@ -29,7 +29,7 @@ class AxiomRule using Condition = AssignedVariable; using Conditions = AssignedVariables; - static AxiomRule fromSAS(utils::Parser<> &parser, const Variables &variables); + static AxiomRule fromSAS(input::Parser<> &parser, const Variables &variables); public: const Conditions &conditions() const; diff --git a/include/plasp/sas/Debugging.h b/include/plasp/sas/Debugging.h index f3d817b..5b00f16 100644 --- a/include/plasp/sas/Debugging.h +++ b/include/plasp/sas/Debugging.h @@ -16,7 +16,7 @@ namespace sas // //////////////////////////////////////////////////////////////////////////////////////////////////// -utils::LogStream &operator<<(utils::LogStream &ostream, const Description &description); +output::ColorStream &operator<<(output::ColorStream &ostream, const Description &description); //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/sas/Description.h b/include/plasp/sas/Description.h index 12fb557..630d6a6 100644 --- a/include/plasp/sas/Description.h +++ b/include/plasp/sas/Description.h @@ -7,13 +7,13 @@ #include +#include #include #include #include #include #include #include -#include namespace plasp { @@ -29,7 +29,7 @@ namespace sas class Description { public: - static Description fromParser(utils::Parser<> &&parser); + static Description fromParser(input::Parser<> &&parser); static Description fromStream(std::istream &istream); static Description fromFile(const boost::filesystem::path &path); @@ -50,16 +50,16 @@ class Description private: Description(); - void parseContent(utils::Parser<> &parser); + void parseContent(input::Parser<> &parser); - void parseVersionSection(utils::Parser<> &parser) const; - void parseMetricSection(utils::Parser<> &parser); - void parseVariablesSection(utils::Parser<> &parser); - void parseMutexSection(utils::Parser<> &parser); - void parseInitialStateSection(utils::Parser<> &parser); - void parseGoalSection(utils::Parser<> &parser); - void parseOperatorSection(utils::Parser<> &parser); - void parseAxiomSection(utils::Parser<> &parser); + void parseVersionSection(input::Parser<> &parser) const; + void parseMetricSection(input::Parser<> &parser); + void parseVariablesSection(input::Parser<> &parser); + void parseMutexSection(input::Parser<> &parser); + void parseInitialStateSection(input::Parser<> &parser); + void parseGoalSection(input::Parser<> &parser); + void parseOperatorSection(input::Parser<> &parser); + void parseAxiomSection(input::Parser<> &parser); bool m_usesActionCosts; diff --git a/include/plasp/sas/Effect.h b/include/plasp/sas/Effect.h index 5a02bae..6fb5d4d 100644 --- a/include/plasp/sas/Effect.h +++ b/include/plasp/sas/Effect.h @@ -3,9 +3,9 @@ #include +#include #include #include -#include namespace plasp { @@ -29,7 +29,7 @@ class Effect using Condition = AssignedVariable; using Conditions = AssignedVariables; - static Effect fromSAS(utils::Parser<> &parser, const Variables &variables, Conditions &preconditions); + static Effect fromSAS(input::Parser<> &parser, const Variables &variables, Conditions &preconditions); public: const Conditions &conditions() const; diff --git a/include/plasp/sas/Goal.h b/include/plasp/sas/Goal.h index ebdca5d..d3057e3 100644 --- a/include/plasp/sas/Goal.h +++ b/include/plasp/sas/Goal.h @@ -1,8 +1,8 @@ #ifndef __PLASP__SAS__GOAL_H #define __PLASP__SAS__GOAL_H +#include #include -#include namespace plasp { @@ -21,7 +21,7 @@ class Goal using Fact = AssignedVariable; using Facts = AssignedVariables; - static Goal fromSAS(utils::Parser<> &parser, const Variables &variables); + static Goal fromSAS(input::Parser<> &parser, const Variables &variables); public: const Facts &facts() const; diff --git a/include/plasp/sas/InitialState.h b/include/plasp/sas/InitialState.h index 92d1576..c1b78e5 100644 --- a/include/plasp/sas/InitialState.h +++ b/include/plasp/sas/InitialState.h @@ -1,8 +1,8 @@ #ifndef __PLASP__SAS__INITIAL_STATE_H #define __PLASP__SAS__INITIAL_STATE_H +#include #include -#include namespace plasp { @@ -21,7 +21,7 @@ class InitialState using Fact = AssignedVariable; using Facts = AssignedVariables; - static InitialState fromSAS(utils::Parser<> &parser, const Variables &variables); + static InitialState fromSAS(input::Parser<> &parser, const Variables &variables); public: const Facts &facts() const; diff --git a/include/plasp/sas/MutexGroup.h b/include/plasp/sas/MutexGroup.h index f16e5e0..ea09316 100644 --- a/include/plasp/sas/MutexGroup.h +++ b/include/plasp/sas/MutexGroup.h @@ -3,8 +3,8 @@ #include +#include #include -#include namespace plasp { @@ -28,7 +28,7 @@ class MutexGroup using Fact = AssignedVariable; using Facts = AssignedVariables; - static MutexGroup fromSAS(utils::Parser<> &parser, const Variables &variables); + static MutexGroup fromSAS(input::Parser<> &parser, const Variables &variables); public: const Facts &facts() const; diff --git a/include/plasp/sas/Operator.h b/include/plasp/sas/Operator.h index 9db777a..2c528a7 100644 --- a/include/plasp/sas/Operator.h +++ b/include/plasp/sas/Operator.h @@ -4,12 +4,12 @@ #include #include +#include +#include #include #include #include #include -#include -#include namespace plasp { @@ -33,10 +33,10 @@ class Operator using Condition = AssignedVariable; using Conditions = AssignedVariables; - static Operator fromSAS(utils::Parser<> &parser, const Variables &variables); + static Operator fromSAS(input::Parser<> &parser, const Variables &variables); public: - void printPredicateAsASP(utils::LogStream &ostream) const; + void printPredicateAsASP(output::ColorStream &stream) const; const Predicate &predicate() const; const Conditions &preconditions() const; diff --git a/include/plasp/sas/Predicate.h b/include/plasp/sas/Predicate.h index a768b05..acd82f4 100644 --- a/include/plasp/sas/Predicate.h +++ b/include/plasp/sas/Predicate.h @@ -5,8 +5,8 @@ #include #include -#include -#include +#include +#include namespace plasp { @@ -22,13 +22,13 @@ namespace sas class Predicate { public: - static Predicate fromSAS(utils::Parser<> &parser); + static Predicate fromSAS(input::Parser<> &parser); using Arguments = std::vector; public: - void printAsSAS(utils::LogStream &outputStream) const; - void printAsASP(utils::LogStream &outputStream) const; + void printAsSAS(output::ColorStream &stream) const; + void printAsASP(output::ColorStream &stream) const; const std::string &name() const; const Arguments &arguments() const; diff --git a/include/plasp/sas/TranslatorASP.h b/include/plasp/sas/TranslatorASP.h index 96692d9..17287df 100644 --- a/include/plasp/sas/TranslatorASP.h +++ b/include/plasp/sas/TranslatorASP.h @@ -1,8 +1,8 @@ #ifndef __PLASP__SAS__TRANSLATOR_ASP_H #define __PLASP__SAS__TRANSLATOR_ASP_H +#include #include -#include #include @@ -20,7 +20,7 @@ namespace sas class TranslatorASP { public: - explicit TranslatorASP(const Description &description, utils::LogStream &outputStream); + explicit TranslatorASP(const Description &description, output::ColorStream &outputStream); void translate() const; @@ -34,7 +34,7 @@ class TranslatorASP void translateAxiomRules() const; const Description &m_description; - utils::LogStream &m_outputStream; + output::ColorStream &m_outputStream; }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/sas/Value.h b/include/plasp/sas/Value.h index 5cc1df4..ea9cfd9 100644 --- a/include/plasp/sas/Value.h +++ b/include/plasp/sas/Value.h @@ -5,8 +5,8 @@ #include #include -#include -#include +#include +#include namespace plasp { @@ -39,14 +39,14 @@ struct Value static const Value Any; static const Value None; - static Value fromSAS(utils::Parser<> &parser); - static const Value &referenceFromSAS(utils::Parser<> &parser, const Variable &variable); + static Value fromSAS(input::Parser<> &parser); + static const Value &referenceFromSAS(input::Parser<> &parser, const Variable &variable); public: Value negated() const; - void printAsSAS(utils::LogStream &outputStream) const; - void printAsASPPredicate(utils::LogStream &outputStream) const; + void printAsSAS(output::ColorStream &stream) const; + void printAsASPPredicate(output::ColorStream &stream) const; Sign sign() const; const std::string &name() const; diff --git a/include/plasp/sas/Variable.h b/include/plasp/sas/Variable.h index ce80363..4a0d719 100644 --- a/include/plasp/sas/Variable.h +++ b/include/plasp/sas/Variable.h @@ -5,9 +5,9 @@ #include #include +#include +#include #include -#include -#include namespace plasp { @@ -28,11 +28,11 @@ using Variables = std::vector; class Variable { public: - static Variable fromSAS(utils::Parser<> &parser); - static const Variable &referenceFromSAS(utils::Parser<> &parser, const Variables &variables); + static Variable fromSAS(input::Parser<> &parser); + static const Variable &referenceFromSAS(input::Parser<> &parser, const Variables &variables); public: - void printNameAsASPPredicate(utils::LogStream &outputStream) const; + void printNameAsASPPredicate(output::ColorStream &outputStream) const; const std::string &name() const; int axiomLayer() const; diff --git a/include/plasp/sas/VariableTransition.h b/include/plasp/sas/VariableTransition.h index 8fd2868..a57eaba 100644 --- a/include/plasp/sas/VariableTransition.h +++ b/include/plasp/sas/VariableTransition.h @@ -3,9 +3,9 @@ #include +#include #include #include -#include namespace plasp { @@ -26,7 +26,7 @@ using VariableTransitions = std::vector; class VariableTransition { public: - static VariableTransition fromSAS(utils::Parser<> &parser, const Variables &variables); + static VariableTransition fromSAS(input::Parser<> &parser, const Variables &variables); public: const Variable &variable() const; diff --git a/include/plasp/utils/LogStream.h b/include/plasp/utils/LogStream.h deleted file mode 100644 index ce8434a..0000000 --- a/include/plasp/utils/LogStream.h +++ /dev/null @@ -1,335 +0,0 @@ -#ifndef __PLASP__UTILS__LOG_STREAM_H -#define __PLASP__UTILS__LOG_STREAM_H - -#include -#include - -namespace plasp -{ -namespace utils -{ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// -// LogStream -// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -enum class StandardStream -{ - Out, - Err -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class LogStream -{ - public: - enum class ColorPolicy - { - Never, - Auto, - Always - }; - - private: - using CharacterType = std::ostream::char_type; - using TraitsType = std::ostream::traits_type; - - public: - LogStream(StandardStream standardStream) - : m_standardStream{standardStream}, - m_colorPolicy{ColorPolicy::Auto} - { - } - - LogStream(const LogStream &other) - : m_standardStream{other.m_standardStream}, - m_colorPolicy{other.m_colorPolicy} - { - } - - LogStream &operator=(const LogStream &other) - { - m_standardStream = other.m_standardStream; - m_colorPolicy = other.m_colorPolicy; - - return *this; - } - - LogStream(LogStream &&other) - : m_standardStream{other.m_standardStream}, - m_colorPolicy{other.m_colorPolicy} - { - other.m_colorPolicy = ColorPolicy::Auto; - } - - LogStream &operator=(LogStream &&other) - { - m_standardStream = other.m_standardStream; - m_colorPolicy = other.m_colorPolicy; - - other.m_colorPolicy = ColorPolicy::Auto; - - return *this; - } - - void setColorPolicy(ColorPolicy colorPolicy) - { - m_colorPolicy = colorPolicy; - } - - bool supportsColor() const - { - if (m_colorPolicy == ColorPolicy::Never) - return false; - - if (m_colorPolicy == ColorPolicy::Always) - return true; - - // Autodetect by checking whether output goes to a terminal - const auto fileDescriptor = - (m_standardStream == utils::StandardStream::Out) - ? STDOUT_FILENO - : STDERR_FILENO; - - return isatty(fileDescriptor); - } - - std::ostream &ostream() - { - return (m_standardStream == utils::StandardStream::Out) - ? std::cout - : std::cerr; - } - - inline LogStream &operator<<(short value); - inline LogStream &operator<<(unsigned short value); - inline LogStream &operator<<(int value); - inline LogStream &operator<<(unsigned int value); - inline LogStream &operator<<(long value); - inline LogStream &operator<<(unsigned long value); - inline LogStream &operator<<(long long value); - inline LogStream &operator<<(unsigned long long value); - inline LogStream &operator<<(float value); - inline LogStream &operator<<(double value); - inline LogStream &operator<<(long double value); - inline LogStream &operator<<(bool value); - inline LogStream &operator<<(const void *value); - inline LogStream &operator<<(const char *value); - inline LogStream &operator<<(const signed char *value); - inline LogStream &operator<<(const unsigned char *value); - inline LogStream &operator<<(std::basic_streambuf *sb); - inline LogStream &operator<<(std::ios_base &(*func)(std::ios_base &)); - inline LogStream &operator<<(std::basic_ios &(*func)(std::basic_ios &)); - inline LogStream &operator<<(std::basic_ostream &(*func)(std::basic_ostream &)); - - inline LogStream &operator<<(char value); - inline LogStream &operator<<(signed char value); - inline LogStream &operator<<(unsigned char value); - - private: - StandardStream m_standardStream; - ColorPolicy m_colorPolicy; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(short value) -{ - ostream() << value; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(unsigned short value) -{ - ostream() << value; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(int value) -{ - ostream() << value; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(unsigned int value) -{ - ostream() << value; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(long value) -{ - ostream() << value; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(unsigned long value) -{ - ostream() << value; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(long long value) -{ - ostream() << value; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(unsigned long long value) -{ - ostream() << value; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(float value) -{ - ostream() << value; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(double value) -{ - ostream() << value; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(long double value) -{ - ostream() << value; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(bool value) -{ - ostream() << value; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(const void *value) -{ - ostream() << value; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(const char *value) -{ - ostream() << value; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(const signed char *value) -{ - ostream() << value; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(const unsigned char *value) -{ - ostream() << value; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(std::basic_streambuf* sb) -{ - ostream() << sb; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(std::ios_base &(*func)(std::ios_base &)) -{ - ostream() << func; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(std::basic_ios &(*func)(std::basic_ios &)) -{ - ostream() << func; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(std::basic_ostream &(*func)(std::basic_ostream &)) -{ - ostream() << func; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -template -inline LogStream &operator<<(LogStream &stream, const std::basic_string &string) -{ - stream.ostream() << string; - return stream; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(char value) -{ - ostream() << value; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(signed char value) -{ - ostream() << value; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &LogStream::operator<<(unsigned char value) -{ - ostream() << value; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -} -} - -#endif diff --git a/include/plasp/utils/Logger.h b/include/plasp/utils/Logger.h deleted file mode 100644 index 3fed423..0000000 --- a/include/plasp/utils/Logger.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef __PLASP__UTILS__LOGGER_H -#define __PLASP__UTILS__LOGGER_H - -#include - -#include -#include -#include - -namespace plasp -{ -namespace utils -{ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Logger -// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class Logger -{ - public: - enum class WarningLevel - { - Normal, - Error, - Ignore - }; - - public: - Logger(); - - Logger(const Logger &other); - Logger &operator=(const Logger &other); - - Logger(Logger &&other); - Logger &operator=(Logger &&other); - - LogStream &outputStream(); - LogStream &errorStream(); - - void setWarningLevel(WarningLevel warningLevel); - void setColorPolicy(LogStream::ColorPolicy colorPolicy); - - void logError(const std::string &message); - void logError(const StreamCoordinate &coordinate, const std::string &message); - void logWarning(const StreamCoordinate &parserCoordinate, const std::string &message); - - private: - LogStream m_outputStream; - LogStream m_errorStream; - - WarningLevel m_warningLevel; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -} -} - -#endif diff --git a/include/plasp/utils/ParserException.h b/include/plasp/utils/ParserException.h deleted file mode 100644 index fb7123c..0000000 --- a/include/plasp/utils/ParserException.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef __PLASP__UTILS__PARSER_EXCEPTION_H -#define __PLASP__UTILS__PARSER_EXCEPTION_H - -#include -#include - -#include - -namespace plasp -{ -namespace utils -{ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// -// ParserException -// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class ParserException: public std::exception -{ - public: - explicit ParserException(const StreamCoordinate &coordinate) - : ParserException(coordinate, "unspecified parser error") - { - } - - explicit ParserException(const StreamCoordinate &coordinate, const char *message) - : ParserException(coordinate, static_cast(message)) - { - } - - explicit ParserException(const StreamCoordinate &coordinate, const std::string &message) - : m_coordinate{coordinate}, - m_message{message}, - m_plainMessage{m_coordinate.sectionName + ":" + std::to_string(m_coordinate.row) - + ":" + std::to_string(m_coordinate.column) + " " + m_message} - { - } - - ~ParserException() throw() - { - } - - const char *what() const throw() - { - return m_plainMessage.c_str(); - } - - const StreamCoordinate &coordinate() const - { - return m_coordinate; - } - - const std::string &message() const - { - return m_message; - } - - private: - StreamCoordinate m_coordinate; - std::string m_message; - std::string m_plainMessage; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -} -} - -#endif diff --git a/lib/catch b/lib/catch new file mode 160000 index 0000000..e27c4ee --- /dev/null +++ b/lib/catch @@ -0,0 +1 @@ +Subproject commit e27c4ee04282f60aefcc9b1062a74f92cf6c1a2b diff --git a/packaging/arch/PKGBUILD b/packaging/arch/PKGBUILD new file mode 100644 index 0000000..1c23b7d --- /dev/null +++ b/packaging/arch/PKGBUILD @@ -0,0 +1,39 @@ +# Maintainer: Patrick Lühne +pkgname=plasp +pkgver=3.0.3 +pkgrel=1 +epoch= +pkgdesc="A translator from PDDL to ASP" +arch=('x86_64' 'i686') +url="https://github.com/potassco/plasp" +license=('MIT') +groups=() +depends=('boost-libs') +makedepends=('boost' 'cmake') +checkdepends=() +optdepends=() +provides=() +conflicts=() +replaces=() +backup=() +options=() +install= +changelog= +source=("https://github.com/potassco/$pkgname/archive/v$pkgver.tar.gz") +noextract=() +md5sums=('2ecd24c675b69fb9fda8c50b8ffefede') +validpgpkeys=() + +build() { + cd "$pkgname-$pkgver" + mkdir build + cd build + cmake .. -DCMAKE_BUILD_TYPE=Release + make +} + +package() { + cd "$pkgname-$pkgver" + install -D build/bin/${pkgname} ${pkgdir}/usr/bin/${pkgname} + install -D -m644 LICENSE.md "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE" +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c1e765b..e74262f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,8 +12,11 @@ file(GLOB pddl_expressions_headers "../include/plasp/pddl/expressions/*.h") file(GLOB sas_sources "plasp/sas/*.cpp") file(GLOB sas_headers "../include/plasp/sas/*.h") -file(GLOB utils_sources "plasp/utils/*.cpp") -file(GLOB utils_headers "../include/plasp/utils/*.h") +file(GLOB input_sources "plasp/input/*.cpp") +file(GLOB input_headers "../include/plasp/input/*.h") + +file(GLOB output_sources "plasp/output/*.cpp") +file(GLOB output_headers "../include/plasp/output/*.h") include_directories( ${Boost_INCLUDE_DIRS} @@ -36,8 +39,11 @@ set(sources ${sas_sources} ${sas_headers} - ${utils_sources} - ${utils_headers} + ${input_sources} + ${input_headers} + + ${output_sources} + ${output_headers} ) set(libraries diff --git a/src/plasp/Language.cpp b/src/plasp/Language.cpp index 6caaeb0..a8c35f2 100644 --- a/src/plasp/Language.cpp +++ b/src/plasp/Language.cpp @@ -17,6 +17,7 @@ using LanguageNames = boost::bimap; //////////////////////////////////////////////////////////////////////////////////////////////////// const LanguageNames languageNames = boost::assign::list_of + (Language::Type::Automatic, "auto") (Language::Type::PDDL, "pddl") (Language::Type::SAS, "sas") (Language::Type::Unknown, "unknown"); diff --git a/src/plasp/utils/Stream.cpp b/src/plasp/input/Stream.cpp similarity index 90% rename from src/plasp/utils/Stream.cpp rename to src/plasp/input/Stream.cpp index 5c196ae..8b66aba 100644 --- a/src/plasp/utils/Stream.cpp +++ b/src/plasp/input/Stream.cpp @@ -1,10 +1,12 @@ -#include +#include #include +#include + namespace plasp { -namespace utils +namespace input { //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -77,7 +79,7 @@ typename Stream::Position Stream::position() const //////////////////////////////////////////////////////////////////////////////////////////////////// -StreamCoordinate Stream::coordinate() const +Location Stream::location() const { const auto currentPosition = position(); @@ -99,7 +101,7 @@ StreamCoordinate Stream::coordinate() const size_t row = 1; size_t column = 1; - // Compute the coordinate character by character + // Compute the location character by character while (true) { if (currentPosition == -1 && atEnd()) @@ -120,7 +122,7 @@ StreamCoordinate Stream::coordinate() const m_stream.ignore(1); } - return {currentFile->sectionName, row, column}; + return {currentFile->sectionName.c_str(), currentFile->sectionName.c_str(), row, row, column, column}; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -142,10 +144,10 @@ bool Stream::atEnd() const void Stream::check() const { if (atEnd()) - throw ParserException(coordinate(), "reading past end of file"); + throw ParserException(location(), "reading past end of file"); if (m_stream.fail()) - throw ParserException(coordinate()); + throw ParserException(location()); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/output/Logger.cpp b/src/plasp/output/Logger.cpp new file mode 100644 index 0000000..3cf57f3 --- /dev/null +++ b/src/plasp/output/Logger.cpp @@ -0,0 +1,180 @@ +#include + +#include + +namespace plasp +{ +namespace output +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Logger +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +constexpr Format priorityFormat(Priority priority) +{ + switch (priority) + { + case Priority::Debug: + return {Color::Green, FontWeight::Bold}; + case Priority::Info: + return {Color::Blue, FontWeight::Bold}; + case Priority::Warning: + return {Color::Magenta, FontWeight::Bold}; + case Priority::Error: + return {Color::Red, FontWeight::Bold}; + } + + return {Color::White, FontWeight::Bold}; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +constexpr const Format MessageBodyFormat = {Color::White, FontWeight::Bold}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +constexpr const Format LocationFormat = {Color::White, FontWeight::Bold}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +Logger::Logger() +: Logger(std::cout, std::cerr) +{ +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +Logger::Logger(ColorStream &&outputStream) +: Logger(std::forward(outputStream), std::cerr) +{ +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +Logger::Logger(ColorStream &&outputStream, ColorStream &&errorStream) +: m_outputStream{outputStream}, + m_errorStream{errorStream}, + m_logPriority{Priority::Warning}, + m_abortPriority{Priority::Error} +{ +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +Logger::Logger(Logger &&other) +: m_outputStream{std::move(other.m_outputStream)}, + m_errorStream{std::move(other.m_errorStream)}, + m_logPriority{other.m_logPriority}, + m_abortPriority{other.m_abortPriority} +{ +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +Logger &Logger::operator=(Logger &&other) +{ + *this = std::move(other); + + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &Logger::outputStream() +{ + return m_outputStream; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ColorStream &Logger::errorStream() +{ + return m_errorStream; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Logger::setLogPriority(Priority logPriority) +{ + m_logPriority = logPriority; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Logger::setAbortPriority(Priority abortPriority) +{ + m_abortPriority = abortPriority; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Logger::setColorPolicy(ColorStream::ColorPolicy colorPolicy) +{ + m_outputStream.setColorPolicy(colorPolicy); + m_errorStream.setColorPolicy(colorPolicy); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Logger::log(Priority priority, const char *message) +{ + const auto priorityID = static_cast(priority); + + if (priorityID < static_cast(m_logPriority)) + return; + + m_errorStream + << priorityFormat(priority) << priorityName(priority) << ":" + << ResetFormat() << " " + << MessageBodyFormat << message + << ResetFormat() << std::endl; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Logger::log(Priority priority, const std::string &message) +{ + log(priority, message.c_str()); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Logger::log(Priority priority, const input::Location &location, const char *message) +{ + const auto priorityID = static_cast(priority); + + // Always show messages that lead to program termination + if (priorityID < static_cast(m_logPriority) && + priorityID < static_cast(m_abortPriority)) + { + return; + } + + m_errorStream + << LocationFormat + << location.sectionStart << ":" << location.rowStart << ":" << location.columnStart << ":" + << ResetFormat() << " " + << priorityFormat(priority) << priorityName(priority) << ":" + << ResetFormat() << " " + << MessageBodyFormat << message + << ResetFormat() << std::endl; + + // TODO: print original warning message + if (priorityID >= static_cast(m_abortPriority)) + throw std::runtime_error("received warning (treated as error by configuration)"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Logger::log(Priority priority, const input::Location &location, const std::string &message) +{ + log(priority, location, message.c_str()); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/src/plasp/pddl/Description.cpp b/src/plasp/pddl/Description.cpp index f497a4e..25db03f 100644 --- a/src/plasp/pddl/Description.cpp +++ b/src/plasp/pddl/Description.cpp @@ -5,9 +5,9 @@ #include +#include #include #include -#include namespace plasp { @@ -20,8 +20,9 @@ namespace pddl // //////////////////////////////////////////////////////////////////////////////////////////////////// -Description::Description() -: m_domainPosition{-1}, +Description::Description(Context &context) +: m_context(context), + m_domainPosition{-1}, m_domain{std::make_unique(Domain(m_context))}, m_problemPosition{-1} { @@ -29,11 +30,10 @@ Description::Description() //////////////////////////////////////////////////////////////////////////////////////////////////// -Description Description::fromContext(Context &&context) +Description Description::fromContext(Context &context) { - Description description; + Description description(context); - description.m_context = std::move(context); description.parse(); return description; @@ -41,9 +41,9 @@ Description Description::fromContext(Context &&context) //////////////////////////////////////////////////////////////////////////////////////////////////// -Description Description::fromStream(std::istream &istream) +Description Description::fromStream(std::istream &istream, Context &context) { - Description description; + Description description(context); description.m_context.parser.read("std::cin", istream); description.parse(); @@ -53,9 +53,9 @@ Description Description::fromStream(std::istream &istream) //////////////////////////////////////////////////////////////////////////////////////////////////// -Description Description::fromFile(const std::string &path) +Description Description::fromFile(const std::string &path, Context &context) { - Description description; + Description description(context); description.m_context.parser.read(path); description.parse(); @@ -65,11 +65,13 @@ Description Description::fromFile(const std::string &path) //////////////////////////////////////////////////////////////////////////////////////////////////// -Description Description::fromFiles(const std::vector &paths) +Description Description::fromFiles(const std::vector &paths, Context &context) { BOOST_ASSERT(!paths.empty()); - Description description; + // TODO: handle dirty context objects (for instance, reused context objects in unit tests) + + Description description(context); std::for_each(paths.cbegin(), paths.cend(), [&](const auto &path) @@ -166,7 +168,7 @@ void Description::findSections() if (parser.testAndSkip("domain")) { if (m_domainPosition != -1) - throw utils::ParserException(parser.coordinate(), "PDDL description may not contain two domains"); + throw input::ParserException(parser.location(), "PDDL description may not contain two domains"); m_domainPosition = position; @@ -176,7 +178,7 @@ void Description::findSections() else if (m_context.parser.testAndSkip("problem")) { if (m_problemPosition != -1) - throw utils::ParserException(parser.coordinate(), "PDDL description may currently not contain two problems"); + throw input::ParserException(parser.location(), "PDDL description may currently not contain two problems"); m_problem = std::make_unique(Problem(m_context, *m_domain)); @@ -188,7 +190,7 @@ void Description::findSections() else { const auto sectionIdentifier = parser.parse(); - throw utils::ParserException(parser.coordinate(), "unknown PDDL section “" + sectionIdentifier + "”"); + throw input::ParserException(parser.location(), "unknown PDDL section “" + sectionIdentifier + "”"); } m_context.parser.skipWhiteSpace(); diff --git a/src/plasp/pddl/Domain.cpp b/src/plasp/pddl/Domain.cpp index 469cabd..07f0cfe 100644 --- a/src/plasp/pddl/Domain.cpp +++ b/src/plasp/pddl/Domain.cpp @@ -2,13 +2,13 @@ #include +#include #include #include #include #include #include #include -#include namespace plasp { @@ -51,7 +51,7 @@ void Domain::findSections() if (unique && sectionPosition != -1) { parser.seek(value); - throw utils::ParserException(parser.coordinate(), "only one “:" + sectionName + "” section allowed"); + throw input::ParserException(parser.location(), "only one “:" + sectionName + "” section allowed"); } sectionPosition = value; @@ -92,7 +92,7 @@ void Domain::findSections() const auto sectionIdentifier = parser.parseIdentifier(); - m_context.logger.logWarning(parser.coordinate(), "section type “" + sectionIdentifier + "” currently unsupported"); + m_context.logger.log(output::Priority::Warning, parser.location(), "section type “" + sectionIdentifier + "” currently unsupported"); parser.seek(sectionIdentifierPosition); } @@ -101,7 +101,7 @@ void Domain::findSections() const auto sectionIdentifier = parser.parseIdentifier(); parser.seek(position); - throw utils::ParserException(parser.coordinate(), "unknown domain section “" + sectionIdentifier + "”"); + throw input::ParserException(parser.location(), "unknown domain section “" + sectionIdentifier + "”"); } // Skip section for now and parse it later @@ -291,7 +291,7 @@ void Domain::checkRequirement(Requirement::Type requirementType) if (hasRequirement(requirementType)) return; - m_context.logger.logWarning(m_context.parser.coordinate(), "requirement “" + Requirement(requirementType).toPDDL() + "” used but never declared"); + m_context.logger.log(output::Priority::Warning, m_context.parser.location(), "requirement “" + Requirement(requirementType).toPDDL() + "” used but never declared"); m_requirements.push_back(requirementType); } @@ -354,7 +354,7 @@ void Domain::parseTypeSection() while (parser.currentCharacter() != ')') { if (parser.currentCharacter() == '(') - throw utils::ParserException(parser.coordinate(), "only primitive types are allowed in type section"); + throw input::ParserException(parser.location(), "only primitive types are allowed in type section"); expressions::PrimitiveType::parseTypedDeclaration(m_context, *this); diff --git a/src/plasp/pddl/Expression.cpp b/src/plasp/pddl/Expression.cpp index e463664..70f811e 100644 --- a/src/plasp/pddl/Expression.cpp +++ b/src/plasp/pddl/Expression.cpp @@ -1,5 +1,7 @@ #include +#include +#include #include #include #include @@ -14,8 +16,6 @@ #include #include #include -#include -#include namespace plasp { @@ -113,9 +113,9 @@ ExpressionPointer Expression::disjunctionNormalized() //////////////////////////////////////////////////////////////////////////////////////////////////// -ExpressionPointer Expression::decomposed(expressions::DerivedPredicates &) +[[ noreturn ]] ExpressionPointer Expression::decomposed(expressions::DerivedPredicates &) { - throw utils::TranslatorException("Expression is not in first-order negation normal form and cannot be decomposed"); + throw output::TranslatorException("Expression is not in first-order negation normal form and cannot be decomposed"); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -227,7 +227,7 @@ ExpressionPointer parseExpression(Context &context, ExpressionContext &expressio const auto expressionIdentifier = parser.parseIdentifier(); parser.seek(position); - throw utils::ParserException(parser.coordinate(), "expression type “" + expressionIdentifier + "” unknown or not allowed in this context"); + throw input::ParserException(parser.location(), "expression type “" + expressionIdentifier + "” unknown or not allowed in this context"); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -302,7 +302,7 @@ ExpressionPointer parseEffectBodyExpression(Context &context, ExpressionContext const auto expressionIdentifier = parser.parseIdentifier(); parser.seek(position); - throw utils::ParserException(parser.coordinate(), "expression type “" + expressionIdentifier + "” unknown or not allowed in this context"); + throw input::ParserException(parser.location(), "expression type “" + expressionIdentifier + "” unknown or not allowed in this context"); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -328,7 +328,7 @@ ExpressionPointer parsePredicate(Context &context, ExpressionContext &expression if ((expression = expressions::Predicate::parse(context, expressionContext))) return expression; - throw utils::ParserException(parser.coordinate(), "expected predicate"); + throw input::ParserException(parser.location(), "expected predicate"); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/pddl/InitialState.cpp b/src/plasp/pddl/InitialState.cpp index cab3750..847e8b0 100644 --- a/src/plasp/pddl/InitialState.cpp +++ b/src/plasp/pddl/InitialState.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -7,7 +8,6 @@ #include #include #include -#include namespace plasp { @@ -58,7 +58,7 @@ std::unique_ptr InitialState::parseDeclaration(Context &context, const auto expressionIdentifier = parser.parseIdentifier(); parser.seek(position); - throw utils::ParserException(parser.coordinate(), "expression type “" + expressionIdentifier + "” unknown or not allowed in this context"); + throw input::ParserException(parser.location(), "expression type “" + expressionIdentifier + "” unknown or not allowed in this context"); }; parser.skipWhiteSpace(); diff --git a/src/plasp/pddl/Problem.cpp b/src/plasp/pddl/Problem.cpp index f4d38fd..1af3523 100644 --- a/src/plasp/pddl/Problem.cpp +++ b/src/plasp/pddl/Problem.cpp @@ -2,12 +2,12 @@ #include +#include #include #include #include #include #include -#include namespace plasp { @@ -52,7 +52,7 @@ void Problem::findSections() if (unique && sectionPosition != -1) { parser.seek(value); - throw utils::ParserException(parser.coordinate(), "only one “:" + sectionName + "” section allowed"); + throw input::ParserException(parser.location(), "only one “:" + sectionName + "” section allowed"); } sectionPosition = value; @@ -88,7 +88,7 @@ void Problem::findSections() const auto sectionIdentifier = parser.parseIdentifier(); - m_context.logger.logWarning(parser.coordinate(), "section type “" + sectionIdentifier + "” currently unsupported"); + m_context.logger.log(output::Priority::Warning, parser.location(), "section type “" + sectionIdentifier + "” currently unsupported"); parser.seek(sectionIdentifierPosition); } @@ -97,7 +97,7 @@ void Problem::findSections() const auto sectionIdentifier = parser.parseIdentifier(); parser.seek(position); - throw utils::ParserException(parser.coordinate(), "unknown problem section “" + sectionIdentifier + "”"); + throw input::ParserException(parser.location(), "unknown problem section “" + sectionIdentifier + "”"); } // Skip section for now and parse it later @@ -203,7 +203,7 @@ void Problem::parseDomainSection() const auto domainName = parser.parseIdentifier(); if (m_domain.name() != domainName) - throw utils::ParserException(parser.coordinate(), "domains do not match (“" + m_domain.name() + "” and “" + domainName + "”)"); + throw input::ParserException(parser.location(), "domains do not match (“" + m_domain.name() + "” and “" + domainName + "”)"); parser.expect(")"); } @@ -260,7 +260,7 @@ void Problem::checkRequirement(Requirement::Type requirementType) if (hasRequirement(requirementType)) return; - m_context.logger.logWarning(m_context.parser.coordinate(), "requirement “" + Requirement(requirementType).toPDDL() + "” used but never declared"); + m_context.logger.log(output::Priority::Warning, m_context.parser.location(), "requirement “" + Requirement(requirementType).toPDDL() + "” used but never declared"); m_requirements.push_back(requirementType); } diff --git a/src/plasp/pddl/Requirement.cpp b/src/plasp/pddl/Requirement.cpp index 75e61eb..0c21dd9 100644 --- a/src/plasp/pddl/Requirement.cpp +++ b/src/plasp/pddl/Requirement.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include namespace plasp { @@ -89,12 +89,12 @@ Requirement Requirement::parse(Context &context) const auto match = requirementTypesToPDDL.right.find(requirementName); if (match == requirementTypesToPDDL.right.end()) - throw utils::ParserException(parser.coordinate(), "unknown PDDL requirement “" + requirementName + "”"); + throw input::ParserException(parser.location(), "unknown PDDL requirement “" + requirementName + "”"); const auto requirementType = match->second; if (requirementType == Requirement::Type::GoalUtilities) - context.logger.logWarning(parser.coordinate(), "requirement “goal-utilities” is not part of the PDDL 3.1 specification"); + context.logger.log(output::Priority::Warning, parser.location(), "requirement “goal-utilities” is not part of the PDDL 3.1 specification"); return Requirement(match->second); } diff --git a/src/plasp/pddl/TranslatorASP.cpp b/src/plasp/pddl/TranslatorASP.cpp index abe7354..8f11828 100644 --- a/src/plasp/pddl/TranslatorASP.cpp +++ b/src/plasp/pddl/TranslatorASP.cpp @@ -2,11 +2,11 @@ #include +#include +#include #include #include #include -#include -#include namespace plasp { @@ -19,7 +19,7 @@ namespace pddl // //////////////////////////////////////////////////////////////////////////////////////////////////// -TranslatorASP::TranslatorASP(Description &description, utils::LogStream &outputStream) +TranslatorASP::TranslatorASP(Description &description, output::ColorStream &outputStream) : m_description(description), m_outputStream(outputStream) { @@ -43,7 +43,7 @@ void TranslatorASP::translate() const void TranslatorASP::translateDomain() const { - m_outputStream << utils::Heading1("domain"); + m_outputStream << output::Heading1("domain"); const auto &domain = m_description.domain(); @@ -77,7 +77,7 @@ void TranslatorASP::translateDomain() const void TranslatorASP::translateTypes() const { - m_outputStream << utils::Heading2("types"); + m_outputStream << output::Heading2("types"); m_outputStream << std::endl; @@ -86,8 +86,8 @@ void TranslatorASP::translateTypes() const if (types.empty()) { m_outputStream - << utils::RuleName("type") << "(" - << utils::Keyword("type") << "(" << utils::String("object") << "))." << std::endl; + << output::Function("type") << "(" + << output::Keyword("type") << "(" << output::String("object") << "))." << std::endl; return; } @@ -96,9 +96,9 @@ void TranslatorASP::translateTypes() const [&](const auto &type) { m_outputStream - << utils::RuleName("type") << "(" - << utils::Keyword("type") << "(" - << utils::String(type->name()) + << output::Function("type") << "(" + << output::Keyword("type") << "(" + << output::String(type->name().c_str()) << "))." << std::endl; const auto &parentTypes = type->parentTypes(); @@ -107,23 +107,23 @@ void TranslatorASP::translateTypes() const [&](const auto &parentType) { m_outputStream - << utils::RuleName("inherits") << "(" << utils::Keyword("type") - << "(" << utils::String(type->name()) << "), " << utils::Keyword("type") - << "(" << utils::String(parentType->name()) << "))." << std::endl; + << output::Function("inherits") << "(" << output::Keyword("type") + << "(" << output::String(type->name().c_str()) << "), " << output::Keyword("type") + << "(" << output::String(parentType->name().c_str()) << "))." << std::endl; }); }); m_outputStream << std::endl - << utils::RuleName("has") << "(" - << utils::Variable("X") << ", " - << utils::Keyword("type") << "(" << utils::Variable("T2") << ")) :- " - << utils::RuleName("has") << "(" - << utils::Variable("X") << ", " - << utils::Keyword("type") << "(" << utils::Variable("T1") << ")), " - << utils::RuleName("inherits") << "(" - << utils::Keyword("type") << "(" << utils::Variable("T1") << "), " - << utils::Keyword("type") << "(" << utils::Variable("T2") << "))." + << output::Function("has") << "(" + << output::Variable("X") << ", " + << output::Keyword("type") << "(" << output::Variable("T2") << ")) :- " + << output::Function("has") << "(" + << output::Variable("X") << ", " + << output::Keyword("type") << "(" << output::Variable("T1") << ")), " + << output::Function("inherits") << "(" + << output::Keyword("type") << "(" << output::Variable("T1") << "), " + << output::Keyword("type") << "(" << output::Variable("T2") << "))." << std::endl; } @@ -131,7 +131,7 @@ void TranslatorASP::translateTypes() const void TranslatorASP::translatePredicates() const { - m_outputStream << utils::Heading2("variables"); + m_outputStream << output::Heading2("variables"); const auto &predicates = m_description.domain().predicates(); @@ -140,12 +140,12 @@ void TranslatorASP::translatePredicates() const { if (predicate->arguments().empty()) { - m_outputStream << utils::String(predicate->name()); + m_outputStream << output::String(predicate->name().c_str()); return; } - m_outputStream << "(" << utils::String(predicate->name()); + m_outputStream << "(" << output::String(predicate->name().c_str()); this->translateVariablesHead(predicate->arguments()); m_outputStream << ")"; }; @@ -155,8 +155,8 @@ void TranslatorASP::translatePredicates() const { m_outputStream << std::endl - << utils::RuleName("variable") << "(" - << utils::Keyword("variable") << "("; + << output::Function("variable") << "(" + << output::Keyword("variable") << "("; printPredicateName(predicate); @@ -169,14 +169,14 @@ void TranslatorASP::translatePredicates() const m_outputStream << std::endl << std::endl - << utils::RuleName("boolean") << "(" << utils::Boolean("true") << ")." << std::endl - << utils::RuleName("boolean") << "(" << utils::Boolean("false") << ")." << std::endl + << output::Function("boolean") << "(" << output::Boolean("true") << ")." << std::endl + << output::Function("boolean") << "(" << output::Boolean("false") << ")." << std::endl << std::endl - << utils::RuleName("contains") << "(" - << utils::Keyword("variable") << "(" << utils::Variable("X") << "), " - << utils::Keyword("value") << "(" << utils::Variable("X") << ", " << utils::Variable("B") << ")) :- " - << utils::RuleName("variable") << "(" << utils::Keyword("variable") << "(" << utils::Variable("X") << ")), " - << utils::RuleName("boolean") << "(" << utils::Variable("B") << ")." + << output::Function("contains") << "(" + << output::Keyword("variable") << "(" << output::Variable("X") << "), " + << output::Keyword("value") << "(" << output::Variable("X") << ", " << output::Variable("B") << ")) :- " + << output::Function("variable") << "(" << output::Keyword("variable") << "(" << output::Variable("X") << ")), " + << output::Function("boolean") << "(" << output::Variable("B") << ")." << std::endl; } @@ -184,23 +184,23 @@ void TranslatorASP::translatePredicates() const void TranslatorASP::translateActions() const { - m_outputStream << utils::Heading2("actions"); + m_outputStream << output::Heading2("actions"); const auto &actions = m_description.domain().actions(); const auto printActionName = [&](const auto &action) { - m_outputStream << utils::Keyword("action") << "("; + m_outputStream << output::Keyword("action") << "("; if (action.parameters().empty()) { - m_outputStream << utils::String(action.name()) << ")"; + m_outputStream << output::String(action.name().c_str()) << ")"; return; } - m_outputStream << "(" << utils::String(action.name()); + m_outputStream << "(" << output::String(action.name().c_str()); this->translateVariablesHead(action.parameters()); m_outputStream << "))"; }; @@ -212,19 +212,19 @@ void TranslatorASP::translateActions() const const auto translateLiteral = [&](const auto &ruleHead, const auto &literal, bool enumerateEffects = false) { - m_outputStream << std::endl << utils::RuleName(ruleHead) << "("; + m_outputStream << std::endl << output::Function(ruleHead) << "("; printActionName(*action); // TODO: implement conditional effects if (enumerateEffects) - m_outputStream << ", " << utils::Keyword("effect") << "(" << utils::Reserved("unconditional") << ")"; + m_outputStream << ", " << output::Keyword("effect") << "(" << output::Reserved("unconditional") << ")"; m_outputStream << ", "; this->translateLiteral(literal); - m_outputStream << ") :- " << utils::RuleName("action") << "("; + m_outputStream << ") :- " << output::Function("action") << "("; printActionName(*action); @@ -234,7 +234,7 @@ void TranslatorASP::translateActions() const m_outputStream << std::endl; // Name - m_outputStream << utils::RuleName("action") << "("; + m_outputStream << output::Function("action") << "("; printActionName(*action); m_outputStream << ")"; @@ -256,7 +256,7 @@ void TranslatorASP::translateActions() const else { if (precondition.expressionType() != Expression::Type::And) - throw utils::TranslatorException("only “and” expressions and (negated) predicates supported as action preconditions currently"); + throw output::TranslatorException("only “and” expressions and (negated) predicates supported as action preconditions currently"); const auto &andExpression = dynamic_cast(precondition); @@ -282,7 +282,7 @@ void TranslatorASP::translateActions() const else { if (effect.expressionType() != Expression::Type::And) - throw utils::TranslatorException("only “and” expressions and (negated) predicates supported as action effects currently"); + throw output::TranslatorException("only “and” expressions and (negated) predicates supported as action effects currently"); const auto &andExpression = dynamic_cast(effect); @@ -302,30 +302,30 @@ void TranslatorASP::translateActions() const void TranslatorASP::translateConstants(const std::string &heading, const expressions::Constants &constants) const { - m_outputStream << utils::Heading2(heading); + m_outputStream << output::Heading2(heading.c_str()); std::for_each(constants.cbegin(), constants.cend(), [&](const auto &constant) { m_outputStream << std::endl - << utils::RuleName("constant") << "(" - << utils::Keyword("constant") << "(" - << utils::String(constant->name()) + << output::Function("constant") << "(" + << output::Keyword("constant") << "(" + << output::String(constant->name().c_str()) << "))." << std::endl; const auto type = constant->type(); if (type != nullptr) { - m_outputStream << utils::RuleName("has") << "(" - << utils::Keyword("constant") << "(" << utils::String(constant->name()) << "), " - << utils::Keyword("type") << "(" << utils::String(type->name()) << "))." << std::endl; + m_outputStream << output::Function("has") << "(" + << output::Keyword("constant") << "(" << output::String(constant->name().c_str()) << "), " + << output::Keyword("type") << "(" << output::String(type->name().c_str()) << "))." << std::endl; } else { - m_outputStream << utils::RuleName("has") << "(" - << utils::Keyword("constant") << "(" << utils::String(constant->name()) << "), " - << utils::Keyword("type") << "(" << utils::String("object") << "))." << std::endl; + m_outputStream << output::Function("has") << "(" + << output::Keyword("constant") << "(" << output::String(constant->name().c_str()) << "), " + << output::Keyword("type") << "(" << output::String("object") << "))." << std::endl; } }); } @@ -341,7 +341,7 @@ void TranslatorASP::translateVariablesHead(const expressions::Variables &variabl { const auto &variable = **i; - m_outputStream << ", " << utils::Variable(variable.name()); + m_outputStream << ", " << output::Variable(variable.name().c_str()); } } @@ -364,19 +364,19 @@ void TranslatorASP::translateVariablesBody(const expressions::Variables &variabl if (variable.type() != nullptr) { if (variable.type()->expressionType() != Expression::Type::PrimitiveType) - throw utils::TranslatorException("only primitive types supported currently"); + throw output::TranslatorException("only primitive types supported currently"); const auto &type = dynamic_cast(*variable.type()); - m_outputStream << utils::RuleName("has") << "(" - << utils::Variable(variable.name()) << ", " - << utils::Keyword("type") << "(" << utils::String(type.name()) << "))"; + m_outputStream << output::Function("has") << "(" + << output::Variable(variable.name().c_str()) << ", " + << output::Keyword("type") << "(" << output::String(type.name().c_str()) << "))"; } else { - m_outputStream << utils::RuleName("has") << "(" - << utils::Variable(variable.name()) << ", " - << utils::Keyword("type") << "(" << utils::String("object") << "))"; + m_outputStream << output::Function("has") << "(" + << output::Variable(variable.name().c_str()) << ", " + << output::Keyword("type") << "(" << output::String("object") << "))"; } } } @@ -390,11 +390,11 @@ void TranslatorASP::translateLiteral(const Expression &literal) const { const auto &predicate = dynamic_cast(literal); - m_outputStream << utils::Keyword("variable") << "("; + m_outputStream << output::Keyword("variable") << "("; this->translatePredicate(predicate); - m_outputStream << "), " << utils::Keyword("value") << "("; + m_outputStream << "), " << output::Keyword("value") << "("; this->translatePredicate(predicate); - m_outputStream << ", " << utils::Boolean("true") << ")"; + m_outputStream << ", " << output::Boolean("true") << ")"; } // Assuming that "not" expression may only contain a predicate else if (literal.expressionType() == Expression::Type::Not) @@ -402,18 +402,18 @@ void TranslatorASP::translateLiteral(const Expression &literal) const const auto ¬Expression = dynamic_cast(literal); if (notExpression.argument()->expressionType() != Expression::Type::Predicate) - throw utils::TranslatorException("only negations of primitive predicates supported as literals currently"); + throw output::TranslatorException("only negations of primitive predicates supported as literals currently"); const auto &predicate = dynamic_cast(*notExpression.argument()); - m_outputStream << utils::Keyword("variable") << "("; + m_outputStream << output::Keyword("variable") << "("; this->translatePredicate(predicate); - m_outputStream << "), " << utils::Keyword("value") << "("; + m_outputStream << "), " << output::Keyword("value") << "("; this->translatePredicate(predicate); - m_outputStream << ", " << utils::Boolean("false") << ")"; + m_outputStream << ", " << output::Boolean("false") << ")"; } else - throw utils::TranslatorException("only primitive predicates and their negations supported as literals currently"); + throw output::TranslatorException("only primitive predicates and their negations supported as literals currently"); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -424,12 +424,12 @@ void TranslatorASP::translatePredicate(const expressions::Predicate &predicate) if (arguments.empty()) { - m_outputStream << utils::String(predicate.name()); + m_outputStream << output::String(predicate.name().c_str()); return; } - m_outputStream << "(" << utils::String(predicate.name()); + m_outputStream << "(" << output::String(predicate.name().c_str()); for (auto i = arguments.cbegin(); i != arguments.cend(); i++) { @@ -439,16 +439,16 @@ void TranslatorASP::translatePredicate(const expressions::Predicate &predicate) { const auto &constant = dynamic_cast(**i); - m_outputStream << utils::Keyword("constant") << "(" << utils::String(constant.name()) << ")"; + m_outputStream << output::Keyword("constant") << "(" << output::String(constant.name().c_str()) << ")"; } else if ((*i)->expressionType() == Expression::Type::Variable) { const auto &variable = dynamic_cast(**i); - m_outputStream << utils::Variable(variable.name()); + m_outputStream << output::Variable(variable.name().c_str()); } else - throw utils::TranslatorException("only variables and constants supported in predicates currently"); + throw output::TranslatorException("only variables and constants supported in predicates currently"); } m_outputStream << ")"; @@ -460,7 +460,7 @@ void TranslatorASP::translateProblem() const { BOOST_ASSERT(m_description.containsProblem()); - m_outputStream << utils::Heading1("problem"); + m_outputStream << output::Heading1("problem"); const auto &problem = m_description.problem(); @@ -486,25 +486,25 @@ void TranslatorASP::translateInitialState() const { BOOST_ASSERT(m_description.containsProblem()); - m_outputStream << utils::Heading2("initial state"); + m_outputStream << output::Heading2("initial state"); const auto &initialStateFacts = m_description.problem().initialState().facts(); std::for_each(initialStateFacts.cbegin(), initialStateFacts.cend(), [&](const auto &fact) { - m_outputStream << std::endl << utils::RuleName("initialState") << "("; + m_outputStream << std::endl << output::Function("initialState") << "("; // Translate single predicate if (fact->expressionType() == Expression::Type::Predicate) { const auto &predicate = dynamic_cast(*fact); - m_outputStream << utils::Keyword("variable") << "("; + m_outputStream << output::Keyword("variable") << "("; this->translatePredicate(predicate); - m_outputStream << "), " << utils::Keyword("value") << "("; + m_outputStream << "), " << output::Keyword("value") << "("; this->translatePredicate(predicate); - m_outputStream << ", " << utils::Boolean("true") << ")"; + m_outputStream << ", " << output::Boolean("true") << ")"; } // Assuming that "not" expression may only contain a predicate else if (fact->expressionType() == Expression::Type::Not) @@ -512,24 +512,24 @@ void TranslatorASP::translateInitialState() const const auto ¬Expression = dynamic_cast(*fact); if (notExpression.argument()->expressionType() != Expression::Type::Predicate) - throw utils::TranslatorException("only negations of simple predicates supported in initial state currently"); + throw output::TranslatorException("only negations of simple predicates supported in initial state currently"); } else - throw utils::TranslatorException("only predicates and their negations supported in initial state currently"); + throw output::TranslatorException("only predicates and their negations supported in initial state currently"); m_outputStream << ")."; }); m_outputStream << std::endl << std::endl - << utils::RuleName("initialState") << "(" - << utils::Keyword("variable") << "(" << utils::Variable("X") << "), " - << utils::Keyword("value") << "(" << utils::Variable("X") << ", " << utils::Boolean("false") << ")) :- " - << utils::RuleName("variable") << "(" << utils::Keyword("variable") << "(" << utils::Variable("X") << ")), " - << utils::Keyword("not") << " " - << utils::RuleName("initialState") << "(" - << utils::Keyword("variable") << "(" << utils::Variable("X") << "), " - << utils::Keyword("value") << "(" << utils::Variable("X") << ", " << utils::Boolean("true") << "))." + << output::Function("initialState") << "(" + << output::Keyword("variable") << "(" << output::Variable("X") << "), " + << output::Keyword("value") << "(" << output::Variable("X") << ", " << output::Boolean("false") << ")) :- " + << output::Function("variable") << "(" << output::Keyword("variable") << "(" << output::Variable("X") << ")), " + << output::Keyword("not") << " " + << output::Function("initialState") << "(" + << output::Keyword("variable") << "(" << output::Variable("X") << "), " + << output::Keyword("value") << "(" << output::Variable("X") << ", " << output::Boolean("true") << "))." << std::endl; } @@ -539,14 +539,14 @@ void TranslatorASP::translateGoal() const { BOOST_ASSERT(m_description.containsProblem()); - m_outputStream << utils::Heading2("goal"); + m_outputStream << output::Heading2("goal"); const auto &goal = m_description.problem().goal(); if (goal.expressionType() == Expression::Type::Predicate || goal.expressionType() == Expression::Type::Not) { - m_outputStream << std::endl << utils::RuleName("goal") << "("; + m_outputStream << std::endl << output::Function("goal") << "("; translateLiteral(goal); @@ -559,7 +559,7 @@ void TranslatorASP::translateGoal() const std::for_each(andExpression.arguments().cbegin(), andExpression.arguments().cend(), [&](const auto argument) { - m_outputStream << std::endl << utils::RuleName("goal") << "("; + m_outputStream << std::endl << output::Function("goal") << "("; this->translateLiteral(*argument); @@ -567,7 +567,7 @@ void TranslatorASP::translateGoal() const }); } else - throw utils::TranslatorException("only single predicates, their negations, and conjunctions are currently supported in the goal"); + throw output::TranslatorException("only single predicates, their negations, and conjunctions are currently supported in the goal"); m_outputStream << std::endl; } diff --git a/src/plasp/pddl/VariableStack.cpp b/src/plasp/pddl/VariableStack.cpp index 54d0f35..3220528 100644 --- a/src/plasp/pddl/VariableStack.cpp +++ b/src/plasp/pddl/VariableStack.cpp @@ -53,7 +53,7 @@ expressions::VariablePointer VariableStack::parseAndFind(plasp::pddl::Context &c return match->get(); } - throw utils::ParserException(parser.coordinate(), "variable “" + variableName + "” used but never declared"); + throw input::ParserException(parser.location(), "variable “" + variableName + "” used but never declared"); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/pddl/expressions/And.cpp b/src/plasp/pddl/expressions/And.cpp index d2de6bc..68cb0df 100644 --- a/src/plasp/pddl/expressions/And.cpp +++ b/src/plasp/pddl/expressions/And.cpp @@ -3,8 +3,8 @@ #include #include +#include #include -#include namespace plasp { @@ -83,7 +83,7 @@ ExpressionPointer And::decomposed(DerivedPredicates &derivedPredicates) if (argument->expressionType() != Expression::Type::Predicate) return; - throw utils::TranslatorException("Expression is not in first-order negation normal form and cannot be decomposed"); + throw output::TranslatorException("Expression is not in first-order negation normal form and cannot be decomposed"); }); return this; diff --git a/src/plasp/pddl/expressions/At.cpp b/src/plasp/pddl/expressions/At.cpp index 54ce459..2b9c6a2 100644 --- a/src/plasp/pddl/expressions/At.cpp +++ b/src/plasp/pddl/expressions/At.cpp @@ -1,6 +1,6 @@ #include -#include +#include namespace plasp { @@ -49,7 +49,7 @@ ExpressionPointer At::argument() const ExpressionPointer At::reduced() { - throw utils::TranslatorException("reducing “at” predicates currently not supported"); + throw output::TranslatorException("reducing “at” predicates currently not supported"); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/pddl/expressions/Constant.cpp b/src/plasp/pddl/expressions/Constant.cpp index b5477e6..4c22f20 100644 --- a/src/plasp/pddl/expressions/Constant.cpp +++ b/src/plasp/pddl/expressions/Constant.cpp @@ -4,6 +4,7 @@ #include +#include #include #include #include @@ -113,7 +114,7 @@ void Constant::parseTypedDeclarations(Context &context, Domain &domain) domain.checkRequirement(Requirement::Type::Typing); // If no types are given, check that typing is not a requirement else if (domain.hasRequirement(Requirement::Type::Typing)) - throw utils::ParserException(parser.coordinate(), "constant has undeclared type"); + throw input::ParserException(parser.location(), "constant has undeclared type"); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -140,7 +141,7 @@ void Constant::parseTypedDeclarations(Context &context, Problem &problem) problem.checkRequirement(Requirement::Type::Typing); // If no types are given, check that typing is not a requirement else if (problem.hasRequirement(Requirement::Type::Typing)) - throw utils::ParserException(parser.coordinate(), "constant has undeclared type"); + throw input::ParserException(parser.location(), "constant has undeclared type"); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -158,7 +159,7 @@ ConstantPointer Constant::parseAndFind(Context &context, const Domain &domain) if (constant != nullptr) return constant; - throw utils::ParserException(parser.coordinate(), "constant “" + constantName + "” used but never declared"); + throw input::ParserException(parser.location(), "constant “" + constantName + "” used but never declared"); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -181,7 +182,7 @@ ConstantPointer Constant::parseAndFind(Context &context, const Problem &problem) if (constant) return constant; - throw utils::ParserException(parser.coordinate(), "constant “" + constantName + "” used but never declared"); + throw input::ParserException(parser.location(), "constant “" + constantName + "” used but never declared"); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/pddl/expressions/Not.cpp b/src/plasp/pddl/expressions/Not.cpp index 19066cd..41785b6 100644 --- a/src/plasp/pddl/expressions/Not.cpp +++ b/src/plasp/pddl/expressions/Not.cpp @@ -1,10 +1,10 @@ #include +#include #include #include #include #include -#include namespace plasp { @@ -189,7 +189,7 @@ ExpressionPointer Not::decomposed(DerivedPredicates &) if (m_argument->expressionType() != Expression::Type::Not && m_argument->expressionType() != Expression::Type::Predicate) { - throw utils::TranslatorException("Expression is not in first-order negation normal form and cannot be decomposed"); + throw output::TranslatorException("Expression is not in first-order negation normal form and cannot be decomposed"); } return this; diff --git a/src/plasp/pddl/expressions/Predicate.cpp b/src/plasp/pddl/expressions/Predicate.cpp index fc10da9..80f34a1 100644 --- a/src/plasp/pddl/expressions/Predicate.cpp +++ b/src/plasp/pddl/expressions/Predicate.cpp @@ -126,7 +126,7 @@ PredicatePointer Predicate::parse(Context &context, const Problem &problem) while (parser.currentCharacter() != ')') { if (parser.currentCharacter() == '?') - throw utils::ParserException(parser.coordinate(), "variables not allowed in this context"); + throw input::ParserException(parser.location(), "variables not allowed in this context"); // Parse objects and constants const auto constant = Constant::parseAndFind(context, problem); diff --git a/src/plasp/pddl/expressions/PrimitiveType.cpp b/src/plasp/pddl/expressions/PrimitiveType.cpp index bd1dc10..b6e84cb 100644 --- a/src/plasp/pddl/expressions/PrimitiveType.cpp +++ b/src/plasp/pddl/expressions/PrimitiveType.cpp @@ -4,6 +4,7 @@ #include +#include #include #include #include @@ -111,7 +112,7 @@ PrimitiveTypePointer PrimitiveType::parseAndFind(Context &context, Domain &domai const auto typeName = parser.parseIdentifier(); if (typeName.empty()) - throw utils::ParserException(parser.coordinate(), "no type supplied"); + throw input::ParserException(parser.location(), "no type supplied"); const auto match = std::find_if(types.cbegin(), types.cend(), [&](const auto &primitiveType) @@ -124,11 +125,11 @@ PrimitiveTypePointer PrimitiveType::parseAndFind(Context &context, Domain &domai // Only "object" is allowed as an implicit type if (typeName == "object" || typeName == "objects") { - context.logger.logWarning(parser.coordinate(), "primitive type “" + typeName + "” should be declared"); + context.logger.log(output::Priority::Warning, parser.location(), "primitive type “" + typeName + "” should be declared"); types.emplace_back(PrimitiveTypePointer(new PrimitiveType(typeName))); } else - throw utils::ParserException(parser.coordinate(), "type “" + typeName + "” used but never declared"); + throw input::ParserException(parser.location(), "type “" + typeName + "” used but never declared"); return types.back().get(); } diff --git a/src/plasp/pddl/expressions/Unsupported.cpp b/src/plasp/pddl/expressions/Unsupported.cpp index 2fd6531..d5f2adb 100644 --- a/src/plasp/pddl/expressions/Unsupported.cpp +++ b/src/plasp/pddl/expressions/Unsupported.cpp @@ -25,7 +25,7 @@ UnsupportedPointer Unsupported::parse(Context &context) expression->m_type = parser.parseIdentifier(); - context.logger.logWarning(parser.coordinate(), "expression type “" + expression->m_type + "” currently unsupported in this context"); + context.logger.log(output::Priority::Warning, parser.location(), "expression type “" + expression->m_type + "” currently unsupported in this context"); skipSection(parser); diff --git a/src/plasp/pddl/expressions/Variable.cpp b/src/plasp/pddl/expressions/Variable.cpp index bc609d0..7c4e3a9 100644 --- a/src/plasp/pddl/expressions/Variable.cpp +++ b/src/plasp/pddl/expressions/Variable.cpp @@ -4,13 +4,13 @@ #include +#include #include #include #include #include #include #include -#include namespace plasp { @@ -60,7 +60,7 @@ void Variable::parseDeclaration(Context &context, Variables ¶meters) }); if (match != parameters.cend()) - throw utils::ParserException(parser.coordinate(), "variable “" + variable->m_name + "” already declared in this scope"); + throw input::ParserException(parser.location(), "variable “" + variable->m_name + "” already declared in this scope"); // Flag variable for potentially upcoming type declaration variable->setDirty(); @@ -138,11 +138,38 @@ void Variable::parseTypedDeclarations(Context &context, ExpressionContext &expre expressionContext.checkRequirement(Requirement::Type::Typing); // If no types are given, check that typing is not a requirement else if (expressionContext.hasRequirement(Requirement::Type::Typing)) - throw utils::ParserException(parser.coordinate(), "variable has undeclared type"); + throw input::ParserException(parser.location(), "variable has undeclared type"); } //////////////////////////////////////////////////////////////////////////////////////////////////// +/* +VariablePointer Variable::parseAndFind(Context &context, const ExpressionContext &expressionContext) +{ + auto &parser = context.parser; + + parser.skipWhiteSpace(); + + parser.expect("?"); + + const auto variableName = parser.parseIdentifier(); + + const auto &variables = expressionContext.parameters; + + const auto match = std::find_if(variables.cbegin(), variables.cend(), + [&](const auto &variable) + { + return variable->name() == variableName; + }); + + if (match == variables.cend()) + throw input::ParserException(parser.location(), "parameter “" + variableName + "” used but never declared"); + + return match->get(); +}*/ + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void Variable::setName(std::string name) { m_name = name; diff --git a/src/plasp/sas/AssignedVariable.cpp b/src/plasp/sas/AssignedVariable.cpp index 8a93e59..6494dae 100644 --- a/src/plasp/sas/AssignedVariable.cpp +++ b/src/plasp/sas/AssignedVariable.cpp @@ -31,7 +31,7 @@ AssignedVariable::AssignedVariable(const Variable &variable, const Value &value) //////////////////////////////////////////////////////////////////////////////////////////////////// -AssignedVariable AssignedVariable::fromSAS(utils::Parser<> &parser, const Variables &variables) +AssignedVariable AssignedVariable::fromSAS(input::Parser<> &parser, const Variables &variables) { AssignedVariable assignedVariable; @@ -43,7 +43,7 @@ AssignedVariable AssignedVariable::fromSAS(utils::Parser<> &parser, const Variab //////////////////////////////////////////////////////////////////////////////////////////////////// -AssignedVariable AssignedVariable::fromSAS(utils::Parser<> &parser, const Variable &variable) +AssignedVariable AssignedVariable::fromSAS(input::Parser<> &parser, const Variable &variable) { AssignedVariable assignedVariable; diff --git a/src/plasp/sas/AxiomRule.cpp b/src/plasp/sas/AxiomRule.cpp index f015706..1f508e8 100644 --- a/src/plasp/sas/AxiomRule.cpp +++ b/src/plasp/sas/AxiomRule.cpp @@ -23,7 +23,7 @@ AxiomRule::AxiomRule(AxiomRule::Conditions conditions, AxiomRule::Condition post //////////////////////////////////////////////////////////////////////////////////////////////////// -AxiomRule AxiomRule::fromSAS(utils::Parser<> &parser, const Variables &variables) +AxiomRule AxiomRule::fromSAS(input::Parser<> &parser, const Variables &variables) { parser.expect("begin_rule"); diff --git a/src/plasp/sas/Debugging.cpp b/src/plasp/sas/Debugging.cpp index 1b30d1e..d12fcf4 100644 --- a/src/plasp/sas/Debugging.cpp +++ b/src/plasp/sas/Debugging.cpp @@ -13,163 +13,163 @@ namespace sas // //////////////////////////////////////////////////////////////////////////////////////////////////// -utils::LogStream &operator<<(utils::LogStream &ostream, const Description &description) +output::ColorStream &operator<<(output::ColorStream &stream, const Description &description) { // Metric section - ostream << "uses action costs: " << (description.usesActionCosts() ? "yes" : "no") << std::endl; + stream << "uses action costs: " << (description.usesActionCosts() ? "yes" : "no") << std::endl; // Variable section const auto &variables = description.variables(); - ostream << "variables: " << variables.size() << std::endl; + stream << "variables: " << variables.size() << std::endl; std::for_each(variables.cbegin(), variables.cend(), [&](const auto &variable) { const auto &values = variable.values(); - ostream << "\t" << variable.name() << ":" << std::endl; - ostream << "\t\tvalues: " << values.size() << std::endl; + stream << "\t" << variable.name() << ":" << std::endl; + stream << "\t\tvalues: " << values.size() << std::endl; std::for_each(values.cbegin(), values.cend(), [&](const auto &value) - { - ostream << "\t\t\t"; - value.printAsSAS(ostream); - ostream << std::endl; + { + stream << "\t\t\t"; + value.printAsSAS(stream); + stream << std::endl; }); - ostream << "\t\taxiom layer: " << variable.axiomLayer() << std::endl; + stream << "\t\taxiom layer: " << variable.axiomLayer() << std::endl; }); // Mutex section const auto &mutexGroups = description.mutexGroups(); - ostream << "mutex groups: " << mutexGroups.size() << std::endl; + stream << "mutex groups: " << mutexGroups.size() << std::endl; std::for_each(mutexGroups.cbegin(), mutexGroups.cend(), [&](const auto &mutexGroup) { - ostream << "\tmutex group:" << std::endl; + stream << "\tmutex group:" << std::endl; std::for_each(mutexGroup.facts().cbegin(), mutexGroup.facts().cend(), [&](const auto &fact) { - ostream << "\t\t" << fact.variable().name() << " = "; - fact.value().printAsSAS(ostream); - ostream << std::endl; + stream << "\t\t" << fact.variable().name() << " = "; + fact.value().printAsSAS(stream); + stream << std::endl; }); }); // Initial state section const auto &initialState = description.initialState(); - ostream << "initial state:" << std::endl; + stream << "initial state:" << std::endl; std::for_each(initialState.facts().cbegin(), initialState.facts().cend(), [&](const auto &fact) { - ostream << "\t" << fact.variable().name() << " = "; - fact.value().printAsSAS(ostream); - ostream << std::endl; + stream << "\t" << fact.variable().name() << " = "; + fact.value().printAsSAS(stream); + stream << std::endl; }); // Goal section const auto &goal = description.goal(); - ostream << "goal:" << std::endl; + stream << "goal:" << std::endl; std::for_each(goal.facts().cbegin(), goal.facts().cend(), [&](const auto &fact) { - ostream << "\t" << fact.variable().name() << " = "; - fact.value().printAsSAS(ostream); - ostream << std::endl; + stream << "\t" << fact.variable().name() << " = "; + fact.value().printAsSAS(stream); + stream << std::endl; }); // Operator section const auto &operators = description.operators(); - ostream << "operators: " << operators.size() << std::endl; + stream << "operators: " << operators.size() << std::endl; std::for_each(operators.cbegin(), operators.cend(), [&](const auto &operator_) { - ostream << "\t"; - operator_.predicate().printAsSAS(ostream); - ostream << ":" << std::endl; + stream << "\t"; + operator_.predicate().printAsSAS(stream); + stream << ":" << std::endl; const auto &preconditions = operator_.preconditions(); - ostream << "\t\tpreconditions: " << preconditions.size() << std::endl; + stream << "\t\tpreconditions: " << preconditions.size() << std::endl; std::for_each(preconditions.cbegin(), preconditions.cend(), [&](const auto &precondition) { std::cout << "\t\t\t" << precondition.variable().name() << " = "; - precondition.value().printAsSAS(ostream); - ostream << std::endl; + precondition.value().printAsSAS(stream); + stream << std::endl; }); const auto &effects = operator_.effects(); - ostream << "\t\teffects: " << effects.size() << std::endl; + stream << "\t\teffects: " << effects.size() << std::endl; std::for_each(effects.cbegin(), effects.cend(), [&](const auto &effect) { - ostream << "\t\t\teffect:" << std::endl; + stream << "\t\t\teffect:" << std::endl; const auto &conditions = effect.conditions(); - ostream << "\t\t\t\tconditions: " << conditions.size() << std::endl; + stream << "\t\t\t\tconditions: " << conditions.size() << std::endl; std::for_each(conditions.cbegin(), conditions.cend(), [&](const auto &condition) { - ostream << "\t\t\t\t\t" << condition.variable().name() << " = "; - condition.value().printAsSAS(ostream); - ostream << std::endl; + stream << "\t\t\t\t\t" << condition.variable().name() << " = "; + condition.value().printAsSAS(stream); + stream << std::endl; }); - ostream << "\t\t\t\tpostcondition:" << std::endl; - ostream << "\t\t\t\t\t" << effect.postcondition().variable().name() << " = "; - effect.postcondition().value().printAsSAS(ostream); - ostream << std::endl; + stream << "\t\t\t\tpostcondition:" << std::endl; + stream << "\t\t\t\t\t" << effect.postcondition().variable().name() << " = "; + effect.postcondition().value().printAsSAS(stream); + stream << std::endl; }); - ostream << "\t\tcosts: " << operator_.costs() << std::endl; + stream << "\t\tcosts: " << operator_.costs() << std::endl; }); // Axiom section const auto &axiomRules = description.axiomRules(); - ostream << "axiom rules: " << axiomRules.size() << std::endl; + stream << "axiom rules: " << axiomRules.size() << std::endl; std::for_each(axiomRules.cbegin(), axiomRules.cend(), [&](const auto &axiomRule) { - ostream << "\taxiom rule:" << std::endl; + stream << "\taxiom rule:" << std::endl; const auto conditions = axiomRule.conditions(); - ostream << "\t\tconditions: " << conditions.size() << std::endl; + stream << "\t\tconditions: " << conditions.size() << std::endl; std::for_each(conditions.cbegin(), conditions.cend(), [&](const auto &condition) { - ostream << "\t\t\t" << condition.variable().name() << " = "; - condition.value().printAsSAS(ostream); - ostream << std::endl; + stream << "\t\t\t" << condition.variable().name() << " = "; + condition.value().printAsSAS(stream); + stream << std::endl; }); - ostream << "\t\tpostcondition:" << std::endl; - ostream << "\t\t\t" << axiomRule.postcondition().variable().name() << " = "; - axiomRule.postcondition().value().printAsSAS(ostream); - ostream << std::endl; + stream << "\t\tpostcondition:" << std::endl; + stream << "\t\t\t" << axiomRule.postcondition().variable().name() << " = "; + axiomRule.postcondition().value().printAsSAS(stream); + stream << std::endl; }); - return ostream; + return stream; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/sas/Description.cpp b/src/plasp/sas/Description.cpp index ab773a1..5315c53 100644 --- a/src/plasp/sas/Description.cpp +++ b/src/plasp/sas/Description.cpp @@ -7,7 +7,7 @@ #include -#include +#include #include namespace plasp @@ -28,7 +28,7 @@ Description::Description() //////////////////////////////////////////////////////////////////////////////////////////////////// -Description Description::fromParser(utils::Parser<> &&parser) +Description Description::fromParser(input::Parser<> &&parser) { Description description; description.parseContent(parser); @@ -40,7 +40,7 @@ Description Description::fromParser(utils::Parser<> &&parser) Description Description::fromStream(std::istream &istream) { - utils::Parser<> parser; + input::Parser<> parser; parser.read("std::cin", istream); Description description; @@ -56,7 +56,7 @@ Description Description::fromFile(const boost::filesystem::path &path) if (!boost::filesystem::is_regular_file(path)) throw std::runtime_error("File does not exist: “" + path.string() + "”"); - utils::Parser<> parser; + input::Parser<> parser; parser.read(path); Description description; @@ -160,7 +160,7 @@ bool Description::hasRequirements() const //////////////////////////////////////////////////////////////////////////////////////////////////// -void Description::parseContent(utils::Parser<> &parser) +void Description::parseContent(input::Parser<> &parser) { parseVersionSection(parser); parseMetricSection(parser); @@ -174,26 +174,26 @@ void Description::parseContent(utils::Parser<> &parser) parser.skipWhiteSpace(); if (!parser.atEnd()) - throw utils::ParserException(parser.coordinate(), "expected end of SAS description (perhaps, input contains two SAS descriptions?)"); + throw input::ParserException(parser.location(), "expected end of SAS description (perhaps, input contains two SAS descriptions?)"); } //////////////////////////////////////////////////////////////////////////////////////////////////// -void Description::parseVersionSection(utils::Parser<> &parser) const +void Description::parseVersionSection(input::Parser<> &parser) const { parser.expect("begin_version"); const auto formatVersion = parser.parse(); if (formatVersion != 3) - throw utils::ParserException(parser.coordinate(), "unsupported SAS format version (" + std::to_string(formatVersion) + ")"); + throw input::ParserException(parser.location(), "unsupported SAS format version (" + std::to_string(formatVersion) + ")"); parser.expect("end_version"); } //////////////////////////////////////////////////////////////////////////////////////////////////// -void Description::parseMetricSection(utils::Parser<> &parser) +void Description::parseMetricSection(input::Parser<> &parser) { parser.expect("begin_metric"); @@ -204,7 +204,7 @@ void Description::parseMetricSection(utils::Parser<> &parser) //////////////////////////////////////////////////////////////////////////////////////////////////// -void Description::parseVariablesSection(utils::Parser<> &parser) +void Description::parseVariablesSection(input::Parser<> &parser) { const auto numberOfVariables = parser.parse(); m_variables.reserve(numberOfVariables); @@ -215,7 +215,7 @@ void Description::parseVariablesSection(utils::Parser<> &parser) //////////////////////////////////////////////////////////////////////////////////////////////////// -void Description::parseMutexSection(utils::Parser<> &parser) +void Description::parseMutexSection(input::Parser<> &parser) { const auto numberOfMutexGroups = parser.parse(); m_mutexGroups.reserve(numberOfMutexGroups); @@ -226,21 +226,21 @@ void Description::parseMutexSection(utils::Parser<> &parser) //////////////////////////////////////////////////////////////////////////////////////////////////// -void Description::parseInitialStateSection(utils::Parser<> &parser) +void Description::parseInitialStateSection(input::Parser<> &parser) { m_initialState = std::make_unique(InitialState::fromSAS(parser, m_variables)); } //////////////////////////////////////////////////////////////////////////////////////////////////// -void Description::parseGoalSection(utils::Parser<> &parser) +void Description::parseGoalSection(input::Parser<> &parser) { m_goal = std::make_unique(Goal::fromSAS(parser, m_variables)); } //////////////////////////////////////////////////////////////////////////////////////////////////// -void Description::parseOperatorSection(utils::Parser<> &parser) +void Description::parseOperatorSection(input::Parser<> &parser) { const auto numberOfOperators = parser.parse(); m_operators.reserve(numberOfOperators); @@ -251,7 +251,7 @@ void Description::parseOperatorSection(utils::Parser<> &parser) //////////////////////////////////////////////////////////////////////////////////////////////////// -void Description::parseAxiomSection(utils::Parser<> &parser) +void Description::parseAxiomSection(input::Parser<> &parser) { const auto numberOfAxiomRules = parser.parse(); m_axiomRules.reserve(numberOfAxiomRules); diff --git a/src/plasp/sas/Effect.cpp b/src/plasp/sas/Effect.cpp index 0fe21e5..0fe0e92 100644 --- a/src/plasp/sas/Effect.cpp +++ b/src/plasp/sas/Effect.cpp @@ -23,7 +23,7 @@ Effect::Effect(Conditions conditions, Condition postcondition) //////////////////////////////////////////////////////////////////////////////////////////////////// -Effect Effect::fromSAS(utils::Parser<> &parser, const Variables &variables, Conditions &preconditions) +Effect Effect::fromSAS(input::Parser<> &parser, const Variables &variables, Conditions &preconditions) { Effect::Conditions conditions; diff --git a/src/plasp/sas/Goal.cpp b/src/plasp/sas/Goal.cpp index 0db7a71..56f0221 100644 --- a/src/plasp/sas/Goal.cpp +++ b/src/plasp/sas/Goal.cpp @@ -13,7 +13,7 @@ namespace sas // //////////////////////////////////////////////////////////////////////////////////////////////////// -Goal Goal::fromSAS(utils::Parser<> &parser, const Variables &variables) +Goal Goal::fromSAS(input::Parser<> &parser, const Variables &variables) { Goal goal; diff --git a/src/plasp/sas/InitialState.cpp b/src/plasp/sas/InitialState.cpp index 60b8f03..7dc46d5 100644 --- a/src/plasp/sas/InitialState.cpp +++ b/src/plasp/sas/InitialState.cpp @@ -11,7 +11,7 @@ namespace sas // //////////////////////////////////////////////////////////////////////////////////////////////////// -InitialState InitialState::fromSAS(utils::Parser<> &parser, const Variables &variables) +InitialState InitialState::fromSAS(input::Parser<> &parser, const Variables &variables) { InitialState initialState; diff --git a/src/plasp/sas/MutexGroup.cpp b/src/plasp/sas/MutexGroup.cpp index 3ee36be..cf45bb5 100644 --- a/src/plasp/sas/MutexGroup.cpp +++ b/src/plasp/sas/MutexGroup.cpp @@ -2,7 +2,7 @@ #include -#include +#include namespace plasp { @@ -15,7 +15,7 @@ namespace sas // //////////////////////////////////////////////////////////////////////////////////////////////////// -MutexGroup MutexGroup::fromSAS(utils::Parser<> &parser, const Variables &variables) +MutexGroup MutexGroup::fromSAS(input::Parser<> &parser, const Variables &variables) { MutexGroup mutexGroup; @@ -29,7 +29,7 @@ MutexGroup MutexGroup::fromSAS(utils::Parser<> &parser, const Variables &variabl mutexGroup.m_facts.emplace_back(Fact::fromSAS(parser, variables)); if (mutexGroup.m_facts[j].value() == Value::None) - throw utils::ParserException(parser.coordinate(), "mutex groups must not contain values"); + throw input::ParserException(parser.location(), "mutex groups must not contain values"); } parser.expect("end_mutex_group"); diff --git a/src/plasp/sas/Operator.cpp b/src/plasp/sas/Operator.cpp index 83bbbcc..2602151 100644 --- a/src/plasp/sas/Operator.cpp +++ b/src/plasp/sas/Operator.cpp @@ -3,8 +3,8 @@ #include #include +#include #include -#include namespace plasp { @@ -17,7 +17,7 @@ namespace sas // //////////////////////////////////////////////////////////////////////////////////////////////////// -Operator Operator::fromSAS(utils::Parser<> &parser, const Variables &variables) +Operator Operator::fromSAS(input::Parser<> &parser, const Variables &variables) { Operator operator_; @@ -46,11 +46,11 @@ Operator Operator::fromSAS(utils::Parser<> &parser, const Variables &variables) //////////////////////////////////////////////////////////////////////////////////////////////////// -void Operator::printPredicateAsASP(utils::LogStream &outputStream) const +void Operator::printPredicateAsASP(output::ColorStream &stream) const { - outputStream << utils::Keyword("action") << "("; - m_predicate.printAsASP(outputStream); - outputStream << ")"; + stream << output::Keyword("action") << "("; + m_predicate.printAsASP(stream); + stream << ")"; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/sas/Predicate.cpp b/src/plasp/sas/Predicate.cpp index d5dd91a..f522ef1 100644 --- a/src/plasp/sas/Predicate.cpp +++ b/src/plasp/sas/Predicate.cpp @@ -4,8 +4,8 @@ #include #include -#include -#include +#include +#include namespace plasp { @@ -18,7 +18,7 @@ namespace sas // //////////////////////////////////////////////////////////////////////////////////////////////////// -Predicate Predicate::fromSAS(utils::Parser<> &parser) +Predicate Predicate::fromSAS(input::Parser<> &parser) { Predicate predicate; @@ -43,7 +43,7 @@ Predicate Predicate::fromSAS(utils::Parser<> &parser) } catch (const std::exception &e) { - throw utils::ParserException(parser.coordinate(), "could not parse operator predicate"); + throw input::ParserException(parser.location(), "could not parse operator predicate"); } return predicate; @@ -65,38 +65,38 @@ const Predicate::Arguments &Predicate::arguments() const //////////////////////////////////////////////////////////////////////////////////////////////////// -void Predicate::printAsSAS(utils::LogStream &outputStream) const +void Predicate::printAsSAS(output::ColorStream &stream) const { if (m_arguments.empty()) { - outputStream << m_name; + stream << m_name; return; } for (size_t i = 0; i < m_arguments.size(); i++) { if (i > 0) - outputStream << " "; + stream << " "; - outputStream << m_arguments[i]; + stream << m_arguments[i]; } } //////////////////////////////////////////////////////////////////////////////////////////////////// -void Predicate::printAsASP(utils::LogStream &outputStream) const +void Predicate::printAsASP(output::ColorStream &stream) const { if (m_arguments.empty()) { - outputStream << utils::String(m_name); + stream << output::String(m_name.c_str()); return; } - outputStream << "(" << utils::String(m_name); + stream << "(" << output::String(m_name.c_str()); for (size_t i = 0; i < m_arguments.size(); i++) - outputStream << ", " << utils::String(m_arguments[i]); + stream << ", " << output::String(m_arguments[i].c_str()); - outputStream << ")"; + stream << ")"; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/sas/TranslatorASP.cpp b/src/plasp/sas/TranslatorASP.cpp index a1ee73f..f185a3b 100644 --- a/src/plasp/sas/TranslatorASP.cpp +++ b/src/plasp/sas/TranslatorASP.cpp @@ -1,6 +1,6 @@ #include -#include +#include namespace plasp { @@ -13,9 +13,9 @@ namespace sas // //////////////////////////////////////////////////////////////////////////////////////////////////// -TranslatorASP::TranslatorASP(const Description &description, utils::LogStream &ostream) +TranslatorASP::TranslatorASP(const Description &description, output::ColorStream &outputStream) : m_description(description), - m_outputStream(ostream) + m_outputStream(outputStream) { } @@ -56,30 +56,30 @@ void TranslatorASP::translate() const void TranslatorASP::translateRequirements() const { - m_outputStream << utils::Heading2("feature requirements") << std::endl; + m_outputStream << output::Heading2("feature requirements") << std::endl; if (m_description.usesActionCosts()) - m_outputStream << utils::RuleName("requires") << "(" << utils::Keyword("feature") << "(" << utils::Reserved("actionCosts") << "))." << std::endl; + m_outputStream << output::Function("requires") << "(" << output::Keyword("feature") << "(" << output::Reserved("actionCosts") << "))." << std::endl; if (m_description.usesAxiomRules()) - m_outputStream << utils::RuleName("requires") << "(" << utils::Keyword("feature") << "(" << utils::Reserved("axiomRules") << "))." << std::endl; + m_outputStream << output::Function("requires") << "(" << output::Keyword("feature") << "(" << output::Reserved("axiomRules") << "))." << std::endl; if (m_description.usesConditionalEffects()) - m_outputStream << utils::RuleName("requires") << "(" << utils::Keyword("feature") << "(" << utils::Reserved("conditionalEffects") << "))." << std::endl; + m_outputStream << output::Function("requires") << "(" << output::Keyword("feature") << "(" << output::Reserved("conditionalEffects") << "))." << std::endl; } //////////////////////////////////////////////////////////////////////////////////////////////////// void TranslatorASP::translateInitialState() const { - m_outputStream << utils::Heading2("initial state") << std::endl; + m_outputStream << output::Heading2("initial state") << std::endl; const auto &initialStateFacts = m_description.initialState().facts(); std::for_each(initialStateFacts.cbegin(), initialStateFacts.cend(), [&](const auto &fact) { - m_outputStream << utils::RuleName("initialState") << "("; + m_outputStream << output::Function("initialState") << "("; fact.variable().printNameAsASPPredicate(m_outputStream); m_outputStream << ", "; fact.value().printAsASPPredicate(m_outputStream); @@ -91,14 +91,14 @@ void TranslatorASP::translateInitialState() const void TranslatorASP::translateGoal() const { - m_outputStream << utils::Heading2("goal") << std::endl; + m_outputStream << output::Heading2("goal") << std::endl; const auto &goalFacts = m_description.goal().facts(); std::for_each(goalFacts.cbegin(), goalFacts.cend(), [&](const auto &fact) { - m_outputStream << utils::RuleName("goal") << "("; + m_outputStream << output::Function("goal") << "("; fact.variable().printNameAsASPPredicate(m_outputStream); m_outputStream << ", "; fact.value().printAsASPPredicate(m_outputStream); @@ -110,7 +110,7 @@ void TranslatorASP::translateGoal() const void TranslatorASP::translateVariables() const { - m_outputStream << utils::Heading2("variables"); + m_outputStream << output::Heading2("variables"); const auto &variables = m_description.variables(); @@ -121,14 +121,14 @@ void TranslatorASP::translateVariables() const BOOST_ASSERT(!values.empty()); - m_outputStream << std::endl << utils::RuleName("variable") << "("; + m_outputStream << std::endl << output::Function("variable") << "("; variable.printNameAsASPPredicate(m_outputStream); m_outputStream << ")." << std::endl; std::for_each(values.cbegin(), values.cend(), [&](const auto &value) { - m_outputStream << utils::RuleName("contains") << "("; + m_outputStream << output::Function("contains") << "("; variable.printNameAsASPPredicate(m_outputStream); m_outputStream << ", "; value.printAsASPPredicate(m_outputStream); @@ -141,7 +141,7 @@ void TranslatorASP::translateVariables() const void TranslatorASP::translateActions() const { - m_outputStream << utils::Heading2("actions"); + m_outputStream << output::Heading2("actions"); const auto &operators = m_description.operators(); @@ -150,7 +150,7 @@ void TranslatorASP::translateActions() const std::for_each(operators.cbegin(), operators.cend(), [&](const auto &operator_) { - m_outputStream << std::endl << utils::RuleName("action") << "("; + m_outputStream << std::endl << output::Function("action") << "("; operator_.printPredicateAsASP(m_outputStream); m_outputStream << ")." << std::endl; @@ -159,7 +159,7 @@ void TranslatorASP::translateActions() const std::for_each(preconditions.cbegin(), preconditions.cend(), [&](const auto &precondition) { - m_outputStream << utils::RuleName("precondition") << "("; + m_outputStream << output::Function("precondition") << "("; operator_.printPredicateAsASP(m_outputStream); m_outputStream << ", "; precondition.variable().printNameAsASPPredicate(m_outputStream); @@ -175,13 +175,13 @@ void TranslatorASP::translateActions() const { const auto &conditions = effect.conditions(); - m_outputStream << utils::RuleName("postcondition") << "("; + m_outputStream << output::Function("postcondition") << "("; operator_.printPredicateAsASP(m_outputStream); if (conditions.empty()) - m_outputStream << ", " << utils::Keyword("effect") << "(" << utils::Reserved("unconditional") << "), "; + m_outputStream << ", " << output::Keyword("effect") << "(" << output::Reserved("unconditional") << "), "; else - m_outputStream << ", " << utils::Keyword("effect") << "(" << utils::Number(std::to_string(currentEffectID)) << "), "; + m_outputStream << ", " << output::Keyword("effect") << "(" << output::Number(currentEffectID) << "), "; effect.postcondition().variable().printNameAsASPPredicate(m_outputStream); m_outputStream << ", "; @@ -193,8 +193,8 @@ void TranslatorASP::translateActions() const { // Conditions of conditional effects m_outputStream - << utils::RuleName("precondition") << "(" - << utils::Keyword("effect") << "(" << utils::Number(std::to_string(currentEffectID)) << "), "; + << output::Function("precondition") << "(" + << output::Keyword("effect") << "(" << output::Number(currentEffectID) << "), "; condition.variable().printNameAsASPPredicate(m_outputStream); m_outputStream << ", "; condition.value().printAsASPPredicate(m_outputStream); @@ -205,9 +205,9 @@ void TranslatorASP::translateActions() const currentEffectID++; }); - m_outputStream << utils::RuleName("costs") << "("; + m_outputStream << output::Function("costs") << "("; operator_.printPredicateAsASP(m_outputStream); - m_outputStream << ", " << utils::Number(std::to_string(operator_.costs())) << ")." << std::endl; + m_outputStream << ", " << output::Number(operator_.costs()) << ")." << std::endl; }); } @@ -215,7 +215,7 @@ void TranslatorASP::translateActions() const void TranslatorASP::translateMutexes() const { - m_outputStream << utils::Heading2("mutex groups"); + m_outputStream << output::Heading2("mutex groups"); const auto &mutexGroups = m_description.mutexGroups(); @@ -229,9 +229,9 @@ void TranslatorASP::translateMutexes() const m_outputStream << std::endl - << utils::RuleName("mutexGroup") << "(" - << utils::Keyword("mutexGroup") << "(" - << utils::Number(mutexGroupID) + << output::Function("mutexGroup") << "(" + << output::Keyword("mutexGroup") << "(" + << output::Number(mutexGroupID) << "))." << std::endl; const auto &facts = mutexGroup.facts(); @@ -239,7 +239,7 @@ void TranslatorASP::translateMutexes() const std::for_each(facts.cbegin(), facts.cend(), [&](const auto &fact) { - m_outputStream << utils::RuleName("contains") << "(" << utils::Keyword("mutexGroup") << "(" << utils::Number(mutexGroupID) << "), "; + m_outputStream << output::Function("contains") << "(" << output::Keyword("mutexGroup") << "(" << output::Number(mutexGroupID) << "), "; fact.variable().printNameAsASPPredicate(m_outputStream); m_outputStream << ", "; fact.value().printAsASPPredicate(m_outputStream); @@ -252,7 +252,7 @@ void TranslatorASP::translateMutexes() const void TranslatorASP::translateAxiomRules() const { - m_outputStream << utils::Heading2("axiom rules"); + m_outputStream << output::Heading2("axiom rules"); const auto &axiomRules = m_description.axiomRules(); @@ -266,9 +266,9 @@ void TranslatorASP::translateAxiomRules() const m_outputStream << std::endl - << utils::RuleName("axiomRule") << "(" - << utils::Keyword("axiomRule") << "(" - << utils::Number(axiomRuleID) + << output::Function("axiomRule") << "(" + << output::Keyword("axiomRule") << "(" + << output::Number(axiomRuleID) << "))." << std::endl; // TODO: Translate axiom rule layer @@ -279,8 +279,8 @@ void TranslatorASP::translateAxiomRules() const [&](const auto &condition) { m_outputStream - << utils::RuleName("precondition") << "(" - << utils::Keyword("axiomRule") << "(" << utils::Number(axiomRuleID) << "), "; + << output::Function("precondition") << "(" + << output::Keyword("axiomRule") << "(" << output::Number(axiomRuleID) << "), "; condition.variable().printNameAsASPPredicate(m_outputStream); m_outputStream << ", "; condition.value().printAsASPPredicate(m_outputStream); @@ -290,9 +290,9 @@ void TranslatorASP::translateAxiomRules() const const auto &postcondition = axiomRule.postcondition(); m_outputStream - << utils::RuleName("postcondition") << "(" - << utils::Keyword("axiomRule") << "(" << utils::Number(axiomRuleID) << "), " - << utils::Keyword("effect") << "(" << utils::Reserved("unconditional") << "), "; + << output::Function("postcondition") << "(" + << output::Keyword("axiomRule") << "(" << output::Number(axiomRuleID) << "), " + << output::Keyword("effect") << "(" << output::Reserved("unconditional") << "), "; postcondition.variable().printNameAsASPPredicate(m_outputStream); m_outputStream << ", "; postcondition.value().printAsASPPredicate(m_outputStream); diff --git a/src/plasp/sas/Value.cpp b/src/plasp/sas/Value.cpp index c266008..322cac4 100644 --- a/src/plasp/sas/Value.cpp +++ b/src/plasp/sas/Value.cpp @@ -2,9 +2,9 @@ #include +#include +#include #include -#include -#include namespace plasp { @@ -54,7 +54,7 @@ Value Value::negated() const //////////////////////////////////////////////////////////////////////////////////////////////////// -Value Value::fromSAS(utils::Parser<> &parser) +Value Value::fromSAS(input::Parser<> &parser) { const auto sasSign = parser.parse(); @@ -74,7 +74,7 @@ Value Value::fromSAS(utils::Parser<> &parser) else if (sasSign == "NegatedAtom") value.m_sign = Value::Sign::Negative; else - throw utils::ParserException(parser.coordinate(), "invalid value sign “" + sasSign + "”"); + throw input::ParserException(parser.location(), "invalid value sign “" + sasSign + "”"); try { @@ -90,7 +90,7 @@ Value Value::fromSAS(utils::Parser<> &parser) } catch (const std::exception &e) { - throw utils::ParserException(parser.coordinate(), std::string("could not parse variable value (") + e.what() + ")"); + throw input::ParserException(parser.location(), std::string("could not parse variable value (") + e.what() + ")"); } return value; @@ -98,7 +98,7 @@ Value Value::fromSAS(utils::Parser<> &parser) //////////////////////////////////////////////////////////////////////////////////////////////////// -const Value &Value::referenceFromSAS(utils::Parser<> &parser, const Variable &variable) +const Value &Value::referenceFromSAS(input::Parser<> &parser, const Variable &variable) { const auto valueID = parser.parse(); @@ -106,7 +106,7 @@ const Value &Value::referenceFromSAS(utils::Parser<> &parser, const Variable &va return Value::Any; if (valueID < 0 || static_cast(valueID) >= variable.values().size()) - throw utils::ParserException(parser.coordinate(), "value index out of range (variable " + variable.name() + ", index " + std::to_string(valueID) + ")"); + throw input::ParserException(parser.location(), "value index out of range (variable " + variable.name() + ", index " + std::to_string(valueID) + ")"); return variable.values()[valueID]; } @@ -127,32 +127,32 @@ const std::string &Value::name() const //////////////////////////////////////////////////////////////////////////////////////////////////// -void Value::printAsASPPredicate(utils::LogStream &outputStream) const +void Value::printAsASPPredicate(output::ColorStream &stream) const { // TODO: do not compare by value if (*this == Value::None) { - outputStream << utils::Keyword("value") << "(" << utils::Reserved("none") << ")"; + stream << output::Keyword("value") << "(" << output::Reserved("none") << ")"; return; } - outputStream << utils::Keyword("value") << "(" << utils::String(m_name) << ", " - << (m_sign == Sign::Positive ? utils::Boolean("true") : utils::Boolean("false")) << ")"; + stream << output::Keyword("value") << "(" << output::String(m_name.c_str()) << ", " + << (m_sign == Sign::Positive ? output::Boolean("true") : output::Boolean("false")) << ")"; } //////////////////////////////////////////////////////////////////////////////////////////////////// -void Value::printAsSAS(utils::LogStream &outputStream) const +void Value::printAsSAS(output::ColorStream &stream) const { if (m_sign == Value::Sign::Positive) - outputStream << "Atom "; + stream << "Atom "; else - outputStream << "NegatedAtom "; + stream << "NegatedAtom "; - outputStream << m_name; + stream << m_name; if (!m_hasArguments) - outputStream << "()"; + stream << "()"; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/sas/Variable.cpp b/src/plasp/sas/Variable.cpp index 70542b8..59071cc 100644 --- a/src/plasp/sas/Variable.cpp +++ b/src/plasp/sas/Variable.cpp @@ -2,8 +2,8 @@ #include -#include -#include +#include +#include namespace plasp { @@ -23,7 +23,7 @@ Variable::Variable() //////////////////////////////////////////////////////////////////////////////////////////////////// -Variable Variable::fromSAS(utils::Parser<> &parser) +Variable Variable::fromSAS(input::Parser<> &parser) { Variable variable; @@ -42,7 +42,7 @@ Variable Variable::fromSAS(utils::Parser<> &parser) // values are only allowed at the end if (j < numberOfValues - 1 && variable.m_values[j] == Value::None) - throw utils::ParserException(parser.coordinate(), " value must be the last value of a variable"); + throw input::ParserException(parser.location(), " value must be the last value of a variable"); } parser.expect("end_variable"); @@ -52,20 +52,20 @@ Variable Variable::fromSAS(utils::Parser<> &parser) //////////////////////////////////////////////////////////////////////////////////////////////////// -void Variable::printNameAsASPPredicate(utils::LogStream &outputStream) const +void Variable::printNameAsASPPredicate(output::ColorStream &stream) const { // TODO: assert that name is a number indeed - outputStream << utils::Keyword("variable") << "(" << utils::Number(m_name) << ")"; + stream << output::Keyword("variable") << "(" << output::Number(m_name) << ")"; } //////////////////////////////////////////////////////////////////////////////////////////////////// -const Variable &Variable::referenceFromSAS(utils::Parser<> &parser, const Variables &variables) +const Variable &Variable::referenceFromSAS(input::Parser<> &parser, const Variables &variables) { const auto variableID = parser.parse(); if (variableID >= variables.size()) - throw utils::ParserException(parser.coordinate(), "variable index out of range (index " + std::to_string(variableID) + ")"); + throw input::ParserException(parser.location(), "variable index out of range (index " + std::to_string(variableID) + ")"); return variables[variableID]; } diff --git a/src/plasp/sas/VariableTransition.cpp b/src/plasp/sas/VariableTransition.cpp index 0c9ee5d..4f6ad26 100644 --- a/src/plasp/sas/VariableTransition.cpp +++ b/src/plasp/sas/VariableTransition.cpp @@ -24,7 +24,7 @@ VariableTransition::VariableTransition() //////////////////////////////////////////////////////////////////////////////////////////////////// -VariableTransition VariableTransition::fromSAS(utils::Parser<> &parser, const Variables &variables) +VariableTransition VariableTransition::fromSAS(input::Parser<> &parser, const Variables &variables) { VariableTransition variableTransition; diff --git a/src/plasp/utils/Logger.cpp b/src/plasp/utils/Logger.cpp deleted file mode 100644 index ea0470f..0000000 --- a/src/plasp/utils/Logger.cpp +++ /dev/null @@ -1,143 +0,0 @@ -#include - -#include - -namespace plasp -{ -namespace utils -{ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Logger -// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -Logger::Logger() -: m_outputStream(StandardStream::Out), - m_errorStream(StandardStream::Err), - m_warningLevel{Logger::WarningLevel::Normal} -{ -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -Logger::Logger(const Logger &other) -: m_outputStream{other.m_outputStream}, - m_errorStream{other.m_errorStream}, - m_warningLevel{other.m_warningLevel} -{ -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -Logger &Logger::operator=(const Logger &other) -{ - m_outputStream = other.m_outputStream; - m_errorStream = other.m_errorStream; - m_warningLevel = other.m_warningLevel; - - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -Logger::Logger(Logger &&other) -: m_outputStream{std::move(other.m_outputStream)}, - m_errorStream{std::move(other.m_errorStream)}, - m_warningLevel{other.m_warningLevel} -{ - other.m_warningLevel = WarningLevel::Normal; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -Logger &Logger::operator=(Logger &&other) -{ - m_outputStream = std::move(other.m_outputStream); - m_errorStream = std::move(other.m_errorStream); - m_warningLevel = other.m_warningLevel; - - other.m_warningLevel = WarningLevel::Normal; - - return *this; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &Logger::outputStream() -{ - return m_outputStream; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -LogStream &Logger::errorStream() -{ - return m_errorStream; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void Logger::setWarningLevel(WarningLevel warningLevel) -{ - m_warningLevel = warningLevel; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void Logger::setColorPolicy(LogStream::ColorPolicy colorPolicy) -{ - m_outputStream.setColorPolicy(colorPolicy); - m_errorStream.setColorPolicy(colorPolicy); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void Logger::logError(const std::string &message) -{ - m_errorStream - << Format(Color::Red, FontWeight::Bold) << "error:" - << ResetFormat() << " " - << Format(Color::White, FontWeight::Bold) << message - << ResetFormat() << std::endl; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void Logger::logError(const StreamCoordinate &coordinate, const std::string &message) -{ - m_errorStream - << Format(Color::White, FontWeight::Bold) << coordinate.sectionName << ":" - << std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) << ":" - << ResetFormat() << " " - << Format(Color::Red, FontWeight::Bold) << "error:" - << ResetFormat() << " " - << Format(Color::White, FontWeight::Bold) << message - << ResetFormat() << std::endl; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void Logger::logWarning(const StreamCoordinate &coordinate, const std::string &message) -{ - if (m_warningLevel == WarningLevel::Ignore) - return; - - if (m_warningLevel == WarningLevel::Error) - throw ParserException(coordinate, message); - - m_errorStream - << Format(Color::White, FontWeight::Bold) << coordinate.sectionName << ":" - << std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) << ":" - << ResetFormat() << " " - << Format(Color::Magenta, FontWeight::Bold) << "warning:" - << ResetFormat() << " " - << Format(Color::White, FontWeight::Bold) << message - << ResetFormat() << std::endl; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -} -} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 91d4840..8ae582e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,18 +2,13 @@ set(target tests) file(GLOB core_sources "*.cpp") -add_subdirectory(googletest) - include_directories( - ${gtest_SOURCE_DIR}/include - ${gtest_SOURCE_DIR} ${Boost_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/include + ${PROJECT_SOURCE_DIR}/lib/catch/single_include ) set(libraries - gtest_main - gtest ${Boost_LIBRARIES} plasp ) @@ -22,7 +17,6 @@ file(COPY data DESTINATION ${CMAKE_BINARY_DIR}) add_executable(${target} ${core_sources}) target_link_libraries(${target} ${libraries}) -add_test(tests ${core_sources}) add_custom_target(run-tests COMMAND ${CMAKE_BINARY_DIR}/bin/tests diff --git a/tests/TestPDDLNormalization.cpp b/tests/TestPDDLNormalization.cpp index 28db35a..33d9f26 100644 --- a/tests/TestPDDLNormalization.cpp +++ b/tests/TestPDDLNormalization.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -13,7 +13,7 @@ using namespace plasp::pddl; //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(PDDLNormalizationTests, Reduce) +TEST_CASE("[PDDL normalization] PDDL expressions are correctly reduced", "[PDDL normalization]") { auto n1 = expressions::NotPointer(new expressions::Not); auto n2 = expressions::NotPointer(new expressions::Not); @@ -36,12 +36,12 @@ TEST(PDDLNormalizationTests, Reduce) std::stringstream output; n1->reduced()->print(output); - ASSERT_EQ(output.str(), "(not (not (and (or (or (not (a)) (b)) (c)) (d))))"); + CHECK(output.str() == "(not (not (and (or (or (not (a)) (b)) (c)) (d))))"); } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(PDDLNormalizationTests, Simplify) +TEST_CASE("[PDDL normalization] PDDL expressions are correctly simplified", "[PDDL normalization]") { auto a1 = expressions::AndPointer(new expressions::And); auto a2 = expressions::AndPointer(new expressions::And); @@ -66,12 +66,12 @@ TEST(PDDLNormalizationTests, Simplify) std::stringstream output; a1->simplified()->print(output); - ASSERT_EQ(output.str(), "(and (a) (b) (c) (d) (or (e) (f) (g) (h)))"); + CHECK(output.str() == "(and (a) (b) (c) (d) (or (e) (f) (g) (h)))"); } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(PDDLNormalizationTests, Implication) +TEST_CASE("[PDDL normalization] Implications are correctly replaced", "[PDDL normalization]") { auto i = expressions::ImplyPointer(new expressions::Imply); @@ -81,12 +81,12 @@ TEST(PDDLNormalizationTests, Implication) std::stringstream output; i->normalized()->print(output); - ASSERT_EQ(output.str(), "(or (not (a)) (b))"); + CHECK(output.str() == "(or (not (a)) (b))"); } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(PDDLNormalizationTests, DoubleNegation) +TEST_CASE("[PDDL normalization] Double negations are correctly replaced", "[PDDL normalization]") { auto n1 = expressions::NotPointer(new expressions::Not); auto n2 = expressions::NotPointer(new expressions::Not); @@ -97,12 +97,12 @@ TEST(PDDLNormalizationTests, DoubleNegation) std::stringstream output; n1->normalized()->print(output); - ASSERT_EQ(output.str(), "(a)"); + CHECK(output.str() == "(a)"); } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(PDDLNormalizationTests, DeMorganNegativeConjunction) +TEST_CASE("[PDDL normalization] De Morgan’s rule is correctly applied to negative conjunctions", "[PDDL normalization]") { auto a = expressions::AndPointer(new expressions::And); a->addArgument(new expressions::Dummy("a")); @@ -115,12 +115,12 @@ TEST(PDDLNormalizationTests, DeMorganNegativeConjunction) std::stringstream output; n->normalized()->print(output); - ASSERT_EQ(output.str(), "(or (not (a)) (not (b)) (not (c)))"); + CHECK(output.str() == "(or (not (a)) (not (b)) (not (c)))"); } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(PDDLNormalizationTests, DeMorganNegativeDisjunction) +TEST_CASE("[PDDL normalization] De Morgan’s rule is correctly applied to negative disjunctions", "[PDDL normalization]") { auto a = expressions::OrPointer(new expressions::Or); a->addArgument(new expressions::Dummy("a")); @@ -133,12 +133,12 @@ TEST(PDDLNormalizationTests, DeMorganNegativeDisjunction) std::stringstream output; n->normalized()->print(output); - ASSERT_EQ(output.str(), "(and (not (a)) (not (b)) (not (c)))"); + CHECK(output.str() == "(and (not (a)) (not (b)) (not (c)))"); } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(PDDLNormalizationTests, DoubleNegationInner) +TEST_CASE("[PDDL normalization] Expressions inside double negations are also normalized", "[PDDL normalization]") { auto n1 = expressions::NotPointer(new expressions::Not); auto n2 = expressions::NotPointer(new expressions::Not); @@ -156,12 +156,12 @@ TEST(PDDLNormalizationTests, DoubleNegationInner) std::stringstream output; n1->normalized()->print(output); - ASSERT_EQ(output.str(), "(or (not (a)) (not (b)) (not (c)))"); + CHECK(output.str() == "(or (not (a)) (not (b)) (not (c)))"); } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(PDDLNormalizationTests, SimplifyNestedForAll) +TEST_CASE("[PDDL normalization] Nested “for all” expressions are correctly simplified", "[PDDL normalization]") { auto v1 = expressions::VariablePointer(new expressions::Variable("x")); auto v2 = expressions::VariablePointer(new expressions::Variable("y")); @@ -182,12 +182,12 @@ TEST(PDDLNormalizationTests, SimplifyNestedForAll) std::stringstream output; f1->normalized()->print(output); - ASSERT_EQ(output.str(), "(forall (?x ?y ?z ?u ?v ?w) (a))"); + CHECK(output.str() == "(forall (?x ?y ?z ?u ?v ?w) (a))"); } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(PDDLNormalizationTests, SimplifyNestedExists) +TEST_CASE("[PDDL normalization] Nested “exists” expressions are correctly simplified", "[PDDL normalization]") { auto v1 = expressions::VariablePointer(new expressions::Variable("x")); auto v2 = expressions::VariablePointer(new expressions::Variable("y")); @@ -208,12 +208,12 @@ TEST(PDDLNormalizationTests, SimplifyNestedExists) std::stringstream output; e1->normalized()->print(output); - ASSERT_EQ(output.str(), "(exists (?x ?y ?z ?u ?v ?w) (a))"); + CHECK(output.str() == "(exists (?x ?y ?z ?u ?v ?w) (a))"); } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(PDDLNormalizationTests, Prenex) +TEST_CASE("[PDDL normalization] Prenex normal form is correctly established", "[PDDL normalization]") { auto a = expressions::AndPointer(new expressions::And); auto f1 = expressions::ForAllPointer(new expressions::ForAll); @@ -238,26 +238,28 @@ TEST(PDDLNormalizationTests, Prenex) auto normalized = a->reduced()->negationNormalized()->prenex(); + SECTION("normalized") { std::stringstream output; normalized->print(output); - ASSERT_EQ(output.str(), "(forall (?x) (forall (?y) (exists (?z) (and (a) (or (b) (c))))))"); + CHECK(output.str() == "(forall (?x) (forall (?y) (exists (?z) (and (a) (or (b) (c))))))"); } - normalized = normalized->simplified(); - + SECTION("simplified") { + normalized = normalized->simplified(); + std::stringstream output; normalized->print(output); - ASSERT_EQ(output.str(), "(forall (?x ?y) (exists (?z) (and (a) (or (b) (c)))))"); + CHECK(output.str() == "(forall (?x ?y) (exists (?z) (and (a) (or (b) (c)))))"); } } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(PDDLNormalizationTests, PrenexGroupSameType) +TEST_CASE("[PDDL normalization] Same-type first-order expressions are correctly grouped in prenex normal form", "[PDDL normalization]") { auto f1 = expressions::ForAllPointer(new expressions::ForAll); auto f2 = expressions::ForAllPointer(new expressions::ForAll); @@ -300,12 +302,12 @@ TEST(PDDLNormalizationTests, PrenexGroupSameType) std::stringstream output; normalized->print(output); - ASSERT_EQ(output.str(), "(forall (?v1 ?v2 ?v6 ?v7) (exists (?v3 ?v8) (forall (?v4 ?v9) (exists (?v5) (and (a) (b))))))"); + CHECK(output.str() == "(forall (?v1 ?v2 ?v6 ?v7) (exists (?v3 ?v8) (forall (?v4 ?v9) (exists (?v5) (and (a) (b))))))"); } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(PDDLNormalizationTests, DisjunctiveNormalForm) +TEST_CASE("[PDDL normalization] Disjunctive normal form is correctly established", "[PDDL normalization]") { auto f = expressions::ForAllPointer(new expressions::ForAll); auto e = expressions::ExistsPointer(new expressions::Exists); @@ -340,7 +342,7 @@ TEST(PDDLNormalizationTests, DisjunctiveNormalForm) std::stringstream output; normalized->print(output); - ASSERT_EQ(output.str(), "(forall (?v1) (exists (?v2) (or " + CHECK(output.str() == "(forall (?v1) (exists (?v2) (or " "(and (a) (b) (c) (f)) " "(h) " "(and (a) (b) (d) (f)) " diff --git a/tests/TestPDDLParser.cpp b/tests/TestPDDLParser.cpp index 96b8e07..e9f87c1 100644 --- a/tests/TestPDDLParser.cpp +++ b/tests/TestPDDLParser.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -17,164 +17,173 @@ using namespace plasp::pddl; //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(PDDLParserTests, ParseBlocksWorldDomain) +TEST_CASE("[PDDL parser] The Blocks World domain is parsed correctly", "[PDDL parser]") { - const auto description = Description::fromFile("data/blocksworld-domain.pddl"); + plasp::output::Logger logger; + Context context(Parser(), logger); - ASSERT_NO_THROW(description.domain()); + const auto description = Description::fromFile("data/blocksworld-domain.pddl", context); + + REQUIRE_NOTHROW(description.domain()); const auto &domain = description.domain(); // Name - ASSERT_EQ(domain.name(), "blocks"); + CHECK(domain.name() == "blocks"); // Requirements - ASSERT_EQ(domain.requirements().size(), 2u); - ASSERT_EQ(domain.requirements()[0].type(), Requirement::Type::STRIPS); - ASSERT_EQ(domain.requirements()[1].type(), Requirement::Type::Typing); + REQUIRE(domain.requirements().size() == 2u); + CHECK(domain.requirements()[0].type() == Requirement::Type::STRIPS); + CHECK(domain.requirements()[1].type() == Requirement::Type::Typing); // Types - ASSERT_EQ(domain.types().size(), 1u); + REQUIRE(domain.types().size() == 1u); const auto &block = *domain.types()[0]; - ASSERT_EQ(block.name(), "block"); - ASSERT_EQ(block.parentTypes().size(), 0u); + CHECK(block.name() == "block"); + REQUIRE(block.parentTypes().size() == 0u); // Predicates - ASSERT_EQ(domain.predicates().size(), 5u); + REQUIRE(domain.predicates().size() == 5u); const auto &on = *domain.predicates()[0]; - ASSERT_EQ(on.name(), "on"); - ASSERT_EQ(on.arguments().size(), 2u); - ASSERT_EQ(on.arguments()[0]->name(), "x"); + CHECK(on.name() == "on"); + REQUIRE(on.arguments().size() == 2u); + CHECK(on.arguments()[0]->name() == "x"); const auto &onArgument0Type = dynamic_cast(*on.arguments()[0]->type()); - ASSERT_EQ(&onArgument0Type, &block); - ASSERT_EQ(on.arguments()[1]->name(), "y"); + CHECK(&onArgument0Type == &block); + CHECK(on.arguments()[1]->name() == "y"); const auto &onArgument1Type = dynamic_cast(*on.arguments()[1]->type()); - ASSERT_EQ(&onArgument1Type, &block); + CHECK(&onArgument1Type == &block); const auto &handempty = *domain.predicates()[3]; - ASSERT_EQ(handempty.name(), "handempty"); - ASSERT_TRUE(handempty.arguments().empty()); + CHECK(handempty.name() == "handempty"); + CHECK(handempty.arguments().empty()); // Actions - ASSERT_EQ(domain.actions().size(), 4u); + REQUIRE(domain.actions().size() == 4u); const auto &pickUp = *domain.actions()[0]; - ASSERT_EQ(pickUp.name(), "pick-up"); - ASSERT_EQ(pickUp.parameters().size(), 1u); - ASSERT_EQ(pickUp.parameters()[0]->name(), "x"); - ASSERT_EQ(pickUp.parameters()[0]->type(), &block); + CHECK(pickUp.name() == "pick-up"); + REQUIRE(pickUp.parameters().size() == 1u); + CHECK(pickUp.parameters()[0]->name() == "x"); + CHECK(pickUp.parameters()[0]->type() == &block); const auto &pickUpPre = dynamic_cast(*pickUp.precondition()); - ASSERT_EQ(pickUpPre.arguments().size(), 3u); + REQUIRE(pickUpPre.arguments().size() == 3u); const auto &pickUpPre0 = dynamic_cast(*pickUpPre.arguments()[0]); - ASSERT_EQ(pickUpPre0.name(), "clear"); - ASSERT_EQ(pickUpPre0.arguments().size(), 1u); + CHECK(pickUpPre0.name() == "clear"); + REQUIRE(pickUpPre0.arguments().size() == 1u); const auto &pickUpPre00 = dynamic_cast(*pickUpPre0.arguments()[0]); - ASSERT_EQ(pickUpPre00.name(), "x"); - ASSERT_EQ(pickUpPre00.type(), &block); - ASSERT_EQ(&pickUpPre00, pickUp.parameters()[0].get()); + CHECK(pickUpPre00.name() == "x"); + CHECK(pickUpPre00.type() == &block); + CHECK(&pickUpPre00 == pickUp.parameters()[0].get()); const auto &pickUpPre2 = dynamic_cast(*pickUpPre.arguments()[2]); - ASSERT_EQ(pickUpPre2.name(), "handempty"); - ASSERT_EQ(pickUpPre2.arguments().size(), 0u); + CHECK(pickUpPre2.name() == "handempty"); + CHECK(pickUpPre2.arguments().empty()); const auto &pickUpEff = dynamic_cast(*pickUp.effect()); - ASSERT_EQ(pickUpEff.arguments().size(), 4u); + REQUIRE(pickUpEff.arguments().size() == 4u); const auto &pickUpEff0 = dynamic_cast(*pickUpEff.arguments()[0]); const auto &pickUpEff00 = dynamic_cast(*pickUpEff0.argument()); - ASSERT_EQ(pickUpEff00.name(), "ontable"); - ASSERT_EQ(pickUpEff00.arguments().size(), 1u); + CHECK(pickUpEff00.name() == "ontable"); + REQUIRE(pickUpEff00.arguments().size() == 1u); const auto &pickUpEff000 = dynamic_cast(*pickUpEff00.arguments()[0]); - ASSERT_EQ(pickUpEff000.name(), "x"); - ASSERT_EQ(pickUpEff000.type(), &block); + CHECK(pickUpEff000.name() == "x"); + CHECK(pickUpEff000.type() == &block); } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(PDDLParserTests, ParseBlocksWorldProblem) +TEST_CASE("[PDDL parser] A Blocks World problem is parsed correctly", "[PDDL parser]") { - const auto description = Description::fromFiles({"data/blocksworld-domain.pddl", "data/blocksworld-problem.pddl"}); + plasp::output::Logger logger; + Context context(Parser(), logger); - ASSERT_NO_THROW(description.problem()); + const auto description = Description::fromFiles({"data/blocksworld-domain.pddl", "data/blocksworld-problem.pddl"}, context); + + REQUIRE_NOTHROW(description.problem()); const auto &problem = description.problem(); // Name - ASSERT_EQ(problem.name(), "blocks-4-0"); - ASSERT_EQ(problem.domain().name(), "blocks"); + CHECK(problem.name() == "blocks-4-0"); + CHECK(problem.domain().name() == "blocks"); // Requirements // TODO: compute domain vs. problem requirements correctly and check them // Objects - ASSERT_EQ(problem.objects().size(), 4u); + REQUIRE(problem.objects().size() == 4u); - ASSERT_EQ(problem.objects()[0]->name(), "d"); - ASSERT_NE(problem.objects()[0]->type(), nullptr); - ASSERT_EQ(problem.objects()[0]->type()->name(), "block"); - ASSERT_EQ(problem.objects()[3]->name(), "c"); - ASSERT_NE(problem.objects()[3]->type(), nullptr); - ASSERT_EQ(problem.objects()[3]->type()->name(), "block"); + CHECK(problem.objects()[0]->name() == "d"); + REQUIRE(problem.objects()[0]->type() != nullptr); + CHECK(problem.objects()[0]->type()->name() == "block"); + CHECK(problem.objects()[3]->name() == "c"); + REQUIRE(problem.objects()[3]->type() != nullptr); + CHECK(problem.objects()[3]->type()->name() == "block"); // Initial State const auto &facts = problem.initialState().facts(); - ASSERT_EQ(facts.size(), 9u); + REQUIRE(facts.size() == 9u); const auto &fact0 = dynamic_cast(*facts[0].get()); - ASSERT_EQ(fact0.name(), "clear"); - ASSERT_EQ(fact0.arguments().size(), 1u); + CHECK(fact0.name() == "clear"); + REQUIRE(fact0.arguments().size() == 1u); const auto &fact00 = dynamic_cast(*fact0.arguments()[0]); - ASSERT_EQ(fact00.name(), "c"); - ASSERT_NE(fact00.type(), nullptr); - ASSERT_EQ(fact00.type()->name(), "block"); + CHECK(fact00.name() == "c"); + REQUIRE(fact00.type() != nullptr); + CHECK(fact00.type()->name() == "block"); const auto &fact8 = dynamic_cast(*facts[8].get()); - ASSERT_EQ(fact8.name(), "handempty"); - ASSERT_EQ(fact8.arguments().size(), 0u); + CHECK(fact8.name() == "handempty"); + REQUIRE(fact8.arguments().size() == 0u); // Goal const auto &goal = dynamic_cast(problem.goal()); - ASSERT_EQ(goal.arguments().size(), 3u); + REQUIRE(goal.arguments().size() == 3u); const auto &goal0 = dynamic_cast(*goal.arguments()[0]); - ASSERT_EQ(goal0.name(), "on"); - ASSERT_EQ(goal0.arguments().size(), 2u); + CHECK(goal0.name() == "on"); + REQUIRE(goal0.arguments().size() == 2u); const auto &goal00 = dynamic_cast(*goal0.arguments()[0]); - ASSERT_EQ(goal00.name(), "d"); + CHECK(goal00.name() == "d"); const auto &goal01 = dynamic_cast(*goal0.arguments()[1]); - ASSERT_EQ(goal01.name(), "c"); + CHECK(goal01.name() == "c"); const auto &goal2 = dynamic_cast(*goal.arguments()[2]); - ASSERT_EQ(goal2.name(), "on"); - ASSERT_EQ(goal2.arguments().size(), 2u); + CHECK(goal2.name() == "on"); + REQUIRE(goal2.arguments().size() == 2u); const auto &goal20 = dynamic_cast(*goal2.arguments()[0]); - ASSERT_EQ(goal20.name(), "b"); + CHECK(goal20.name() == "b"); const auto &goal21 = dynamic_cast(*goal2.arguments()[1]); - ASSERT_EQ(goal21.name(), "a"); + CHECK(goal21.name() == "a"); } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(PDDLParserTests, ParseStorageDomain) +TEST_CASE("[PDDL parser] The Storage domain is parsed correctly", "[PDDL parser]") { - const auto description = plasp::pddl::Description::fromFile("data/storage-domain.pddl"); + plasp::output::Logger logger; + Context context(Parser(), logger); - ASSERT_NO_THROW(description.domain()); + const auto description = plasp::pddl::Description::fromFile("data/storage-domain.pddl", context); + + REQUIRE_NOTHROW(description.domain()); const auto &domain = description.domain(); // Name - ASSERT_EQ(domain.name(), "storage-propositional"); + CHECK(domain.name() == "storage-propositional"); // Requirements - ASSERT_EQ(domain.requirements().size(), 1u); - ASSERT_EQ(domain.requirements()[0].type(), Requirement::Type::Typing); + REQUIRE(domain.requirements().size() == 1u); + CHECK(domain.requirements()[0].type() == Requirement::Type::Typing); // Types - ASSERT_EQ(domain.types().size(), 10u); + REQUIRE(domain.types().size() == 10u); const auto &hoist = *domain.types()[0]; const auto &surface = *domain.types()[1]; @@ -184,140 +193,146 @@ TEST(PDDLParserTests, ParseStorageDomain) const auto &crate = *domain.types()[9]; const auto &hoistParents = hoist.parentTypes(); - ASSERT_EQ(hoistParents.size(), 1u); - ASSERT_TRUE(std::find(hoistParents.cbegin(), hoistParents.cend(), &object) != hoistParents.cend()); + REQUIRE(hoistParents.size() == 1u); + CHECK(std::find(hoistParents.cbegin(), hoistParents.cend(), &object) != hoistParents.cend()); const auto &areaParents = area.parentTypes(); - ASSERT_EQ(areaParents.size(), 2u); - ASSERT_TRUE(std::find(areaParents.cbegin(), areaParents.cend(), &object) != areaParents.cend()); - ASSERT_TRUE(std::find(areaParents.cbegin(), areaParents.cend(), &surface) != areaParents.cend()); + REQUIRE(areaParents.size() == 2u); + CHECK(std::find(areaParents.cbegin(), areaParents.cend(), &object) != areaParents.cend()); + CHECK(std::find(areaParents.cbegin(), areaParents.cend(), &surface) != areaParents.cend()); // Predicates - ASSERT_EQ(domain.predicates().size(), 8u); + REQUIRE(domain.predicates().size() == 8u); const auto &on = *domain.predicates()[5]; - ASSERT_EQ(on.name(), "on"); - ASSERT_EQ(on.arguments().size(), 2u); - ASSERT_EQ(on.arguments()[0]->name(), "c"); + CHECK(on.name() == "on"); + REQUIRE(on.arguments().size() == 2u); + CHECK(on.arguments()[0]->name() == "c"); const auto &onArgument0Type = dynamic_cast(*on.arguments()[0]->type()); - ASSERT_EQ(&onArgument0Type, &crate); - ASSERT_EQ(on.arguments()[1]->name(), "s"); + CHECK(&onArgument0Type == &crate); + CHECK(on.arguments()[1]->name() == "s"); const auto &onArgument1Type = dynamic_cast(*on.arguments()[1]->type()); - ASSERT_EQ(&onArgument1Type, &storearea); + CHECK(&onArgument1Type == &storearea); const auto &in = *domain.predicates()[1]; - ASSERT_EQ(in.name(), "in"); - ASSERT_EQ(in.arguments().size(), 2u); - ASSERT_EQ(in.arguments()[0]->name(), "x"); + CHECK(in.name() == "in"); + REQUIRE(in.arguments().size() == 2u); + CHECK(in.arguments()[0]->name() == "x"); const auto &inArgument0Type = dynamic_cast(*in.arguments()[0]->type()); - ASSERT_EQ(inArgument0Type.arguments().size(), 2u); + REQUIRE(inArgument0Type.arguments().size() == 2u); const auto &inArgument0Type0 = dynamic_cast(*inArgument0Type.arguments()[0]); - ASSERT_EQ(&inArgument0Type0, &storearea); + CHECK(&inArgument0Type0 == &storearea); const auto &inArgument0Type1 = dynamic_cast(*inArgument0Type.arguments()[1]); - ASSERT_EQ(&inArgument0Type1, &crate); + CHECK(&inArgument0Type1 == &crate); // Actions - ASSERT_EQ(domain.actions().size(), 5u); + REQUIRE(domain.actions().size() == 5u); const auto &drop = *domain.actions()[1]; - ASSERT_EQ(drop.name(), "drop"); - ASSERT_EQ(drop.parameters().size(), 5u); - ASSERT_EQ(drop.parameters()[3]->name(), "a2"); - ASSERT_EQ(drop.parameters()[3]->type(), &area); + CHECK(drop.name() == "drop"); + REQUIRE(drop.parameters().size() == 5u); + CHECK(drop.parameters()[3]->name() == "a2"); + CHECK(drop.parameters()[3]->type() == &area); const auto &dropPre = dynamic_cast(*drop.precondition()); - ASSERT_EQ(dropPre.arguments().size(), 5u); + REQUIRE(dropPre.arguments().size() == 5u); const auto &dropPre2 = dynamic_cast(*dropPre.arguments()[2]); - ASSERT_EQ(dropPre2.name(), "lifting"); - ASSERT_EQ(dropPre2.arguments().size(), 2u); + CHECK(dropPre2.name() == "lifting"); + REQUIRE(dropPre2.arguments().size() == 2u); const auto &dropPre21 = dynamic_cast(*dropPre2.arguments()[1]); - ASSERT_EQ(dropPre21.name(), "c"); - ASSERT_EQ(dropPre21.type(), &crate); + CHECK(dropPre21.name() == "c"); + CHECK(dropPre21.type() == &crate); const auto &dropEff = dynamic_cast(*drop.effect()); - ASSERT_EQ(dropEff.arguments().size(), 5u); + REQUIRE(dropEff.arguments().size() == 5u); const auto &dropEff2 = dynamic_cast(*dropEff.arguments()[2]); const auto &dropEff20 = dynamic_cast(*dropEff2.argument()); - ASSERT_EQ(dropEff20.name(), "clear"); - ASSERT_EQ(dropEff20.arguments().size(), 1u); + CHECK(dropEff20.name() == "clear"); + REQUIRE(dropEff20.arguments().size() == 1u); const auto &dropEff200 = dynamic_cast(*dropEff20.arguments()[0]); - ASSERT_EQ(dropEff200.name(), "a1"); - ASSERT_EQ(dropEff200.type(), &storearea); + CHECK(dropEff200.name() == "a1"); + CHECK(dropEff200.type() == &storearea); } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(PDDLParserTests, ParseStorageProblem) +TEST_CASE("[PDDL parser] A Storage problem is parsed correctly", "[PDDL parser]") { - const auto description = Description::fromFiles({"data/storage-domain.pddl", "data/storage-problem.pddl"}); + plasp::output::Logger logger; + Context context(Parser(), logger); - ASSERT_NO_THROW(description.problem()); + const auto description = Description::fromFiles({"data/storage-domain.pddl", "data/storage-problem.pddl"}, context); + + REQUIRE_NOTHROW(description.problem()); const auto &problem = description.problem(); // Name - ASSERT_EQ(problem.name(), "storage-1"); - ASSERT_EQ(problem.domain().name(), "storage-propositional"); + CHECK(problem.name() == "storage-1"); + CHECK(problem.domain().name() == "storage-propositional"); // Requirements // TODO: compute domain vs. problem requirements correctly and check them // Objects - ASSERT_EQ(problem.objects().size(), 7u); + REQUIRE(problem.objects().size() == 7u); - ASSERT_EQ(problem.objects()[0]->name(), "depot0-1-1"); - ASSERT_NE(problem.objects()[0]->type(), nullptr); - ASSERT_EQ(problem.objects()[0]->type()->name(), "storearea"); - ASSERT_EQ(problem.objects()[6]->name(), "loadarea"); - ASSERT_NE(problem.objects()[6]->type(), nullptr); - ASSERT_EQ(problem.objects()[6]->type()->name(), "transitarea"); + CHECK(problem.objects()[0]->name() == "depot0-1-1"); + REQUIRE(problem.objects()[0]->type() != nullptr); + CHECK(problem.objects()[0]->type()->name() == "storearea"); + CHECK(problem.objects()[6]->name() == "loadarea"); + REQUIRE(problem.objects()[6]->type() != nullptr); + CHECK(problem.objects()[6]->type()->name() == "transitarea"); // Initial State const auto &facts = problem.initialState().facts(); - ASSERT_EQ(facts.size(), 10u); + REQUIRE(facts.size() == 10u); const auto &fact0 = dynamic_cast(*facts[0].get()); - ASSERT_EQ(fact0.name(), "in"); - ASSERT_EQ(fact0.arguments().size(), 2u); + CHECK(fact0.name() == "in"); + REQUIRE(fact0.arguments().size() == 2u); const auto &fact01 = dynamic_cast(*fact0.arguments()[1]); - ASSERT_EQ(fact01.name(), "depot0"); - ASSERT_NE(fact01.type(), nullptr); - ASSERT_EQ(fact01.type()->name(), "depot"); + CHECK(fact01.name() == "depot0"); + REQUIRE(fact01.type() != nullptr); + CHECK(fact01.type()->name() == "depot"); const auto &fact9 = dynamic_cast(*facts[9].get()); - ASSERT_EQ(fact9.name(), "available"); - ASSERT_EQ(fact9.arguments().size(), 1u); + CHECK(fact9.name() == "available"); + REQUIRE(fact9.arguments().size() == 1u); const auto &fact90 = dynamic_cast(*fact9.arguments()[0]); - ASSERT_EQ(fact90.name(), "hoist0"); - ASSERT_NE(fact90.type(), nullptr); - ASSERT_EQ(fact90.type()->name(), "hoist"); + CHECK(fact90.name() == "hoist0"); + REQUIRE(fact90.type() != nullptr); + CHECK(fact90.type()->name() == "hoist"); // Goal const auto &goal = dynamic_cast(problem.goal()); - ASSERT_EQ(goal.arguments().size(), 1u); + REQUIRE(goal.arguments().size() == 1u); const auto &goal0 = dynamic_cast(*goal.arguments()[0]); - ASSERT_EQ(goal0.name(), "in"); - ASSERT_EQ(goal0.arguments().size(), 2u); + CHECK(goal0.name() == "in"); + REQUIRE(goal0.arguments().size() == 2u); const auto &goal00 = dynamic_cast(*goal0.arguments()[0]); - ASSERT_EQ(goal00.name(), "crate0"); + CHECK(goal00.name() == "crate0"); const auto &goal01 = dynamic_cast(*goal0.arguments()[1]); - ASSERT_EQ(goal01.name(), "depot0"); + CHECK(goal01.name() == "depot0"); } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(PDDLParserTests, ParseConstants) +TEST_CASE("[PDDL parser] Constants are parsed correctly", "[PDDL parser]") { - const auto description = Description::fromFile("data/woodworking-domain.pddl"); + plasp::output::Logger logger; + Context context(Parser(), logger); - ASSERT_NO_THROW(description.domain()); + const auto description = Description::fromFile("data/woodworking-domain.pddl", context); + + REQUIRE_NOTHROW(description.domain()); const auto &domain = description.domain(); // Name - ASSERT_EQ(domain.name(), "woodworking"); + CHECK(domain.name() == "woodworking"); // Types const auto &acolour = *domain.types()[0]; @@ -325,82 +340,193 @@ TEST(PDDLParserTests, ParseConstants) const auto &treatmentstatus = *domain.types()[5]; // Constants - ASSERT_EQ(domain.constants().size(), 8u); - ASSERT_EQ(domain.constants()[0]->type(), &surface); - ASSERT_EQ(domain.constants()[2]->type(), &surface); - ASSERT_EQ(domain.constants()[3]->type(), &treatmentstatus); - ASSERT_EQ(domain.constants()[6]->type(), &treatmentstatus); - ASSERT_EQ(domain.constants()[7]->type(), &acolour); + REQUIRE(domain.constants().size() == 8u); + CHECK(domain.constants()[0]->type() == &surface); + CHECK(domain.constants()[2]->type() == &surface); + CHECK(domain.constants()[3]->type() == &treatmentstatus); + CHECK(domain.constants()[6]->type() == &treatmentstatus); + CHECK(domain.constants()[7]->type() == &acolour); // TODO: add test with constants in predicates } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(PDDLParserTests, ParseWithWhiteSpace) +TEST_CASE("[PDDL parser] White spaces are ignored", "[PDDL parser]") { - ASSERT_NO_THROW(Description::fromFile("data/white-space-test.pddl")); + plasp::output::Logger logger; + Context context(Parser(), logger); + + CHECK_NOTHROW(Description::fromFile("data/white-space-test.pddl", context)); } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(PDDLParserTests, DetectWrongDomain) +TEST_CASE("[PDDL parser] Missing or unmatching domain descriptions are detected", "[PDDL parser]") { - ASSERT_THROW(Description::fromFile("data/blocksworld-problem.pddl"), ConsistencyException); - ASSERT_THROW(Description::fromFiles({"data/blocksworld-problem.pddl", "data/storage-domain.pddl"}), plasp::utils::ParserException); + plasp::output::Logger logger; + Context context(Parser(), logger); + + SECTION("") + { + CHECK_THROWS_AS(Description::fromFile("data/blocksworld-problem.pddl", context), ConsistencyException); + } + SECTION("") + { + CHECK_THROWS_AS(Description::fromFiles({"data/blocksworld-problem.pddl", "data/storage-domain.pddl"}, context), plasp::input::ParserException); + } } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(PDDLParserTests, DetectSyntaxErrors) +TEST_CASE("[PDDL parser] Common PDDL syntax errors are detected", "[PDDL parser]") { - ASSERT_NO_THROW(Description::fromFile("data/pddl-syntax/domain-valid.pddl")); + plasp::output::Logger logger; + Context context(Parser(), logger); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-expressions-1.pddl")); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-expressions-2.pddl")); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-expressions-3.pddl")); + SECTION("") + { + CHECK_NOTHROW(Description::fromFile("data/pddl-syntax/domain-valid.pddl", context)); + } - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-expression-name-1.pddl")); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-expression-name-2.pddl")); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-expression-name-3.pddl")); + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-expressions-1.pddl", context)); + } + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-expressions-2.pddl", context)); + } + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-expressions-3.pddl", context)); + } - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-parentheses-1.pddl")); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-parentheses-2.pddl")); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-parentheses-3.pddl")); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-parentheses-4.pddl")); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-parentheses-5.pddl")); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-parentheses-6.pddl")); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-parentheses-7.pddl")); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-parentheses-8.pddl")); + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-expression-name-1.pddl", context)); + } + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-expression-name-2.pddl", context)); + } + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-expression-name-3.pddl", context)); + } - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-section-name-1.pddl")); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-section-name-2.pddl")); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-section-name-3.pddl")); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-section-name-4.pddl")); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-section-name-5.pddl")); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-section-name-6.pddl")); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-section-name-7.pddl")); + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-parentheses-1.pddl", context)); + } + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-parentheses-2.pddl", context)); + } + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-parentheses-3.pddl", context)); + } + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-parentheses-4.pddl", context)); + } + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-parentheses-5.pddl", context)); + } + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-parentheses-6.pddl", context)); + } + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-parentheses-7.pddl", context)); + } + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-parentheses-8.pddl", context)); + } - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-types-1.pddl")); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-types-2.pddl")); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-types-3.pddl")); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-types-4.pddl")); + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-section-name-1.pddl", context)); + } + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-section-name-2.pddl", context)); + } + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-section-name-3.pddl", context)); + } + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-section-name-4.pddl", context)); + } + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-section-name-5.pddl", context)); + } + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-section-name-6.pddl", context)); + } + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-section-name-7.pddl", context)); + } - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-variables-1.pddl")); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-variables-2.pddl")); - ASSERT_ANY_THROW(Description::fromFile("data/pddl-syntax/domain-variables-3.pddl")); + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-types-1.pddl", context)); + } + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-types-2.pddl", context)); + } + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-types-3.pddl", context)); + } + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-types-4.pddl", context)); + } + + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-variables-1.pddl", context)); + } + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-variables-2.pddl", context)); + } + SECTION("") + { + CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-variables-3.pddl", context)); + } } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(PDDLParserTests, CheckIssues) +TEST_CASE("[PDDL parser] Former issues are fixed", "[PDDL parser]") { - // Check white space issues with constants and parsing unsupported sections - ASSERT_NO_THROW(Description::fromFile("data/issues/issue-1.pddl")); + plasp::output::Logger logger; + Context context(Parser(), logger); - // Check white space issues with empty n-ary predicates - ASSERT_NO_THROW(Description::fromFile("data/issues/issue-2.pddl")); + SECTION("white space issues with constants and parsing unsupported sections") + { + CHECK_NOTHROW(Description::fromFile("data/issues/issue-1.pddl", context)); + } - // Check that comments are correctly ignored - ASSERT_NO_THROW(Description::fromFile("data/issues/issue-3.pddl")); + SECTION("white space issues with empty n-ary predicates") + { + CHECK_NOTHROW(Description::fromFile("data/issues/issue-2.pddl", context)); + } + + SECTION("comments are correctly ignored") + { + CHECK_NOTHROW(Description::fromFile("data/issues/issue-3.pddl", context)); + } } diff --git a/tests/TestPDDLTranslation.cpp b/tests/TestPDDLTranslation.cpp index f698174..5af32c1 100644 --- a/tests/TestPDDLTranslation.cpp +++ b/tests/TestPDDLTranslation.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -12,19 +12,22 @@ boost::iostreams::stream nullStream((boost::iostrea //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(PDDLTranslationTests, CheckIssues) +TEST_CASE("[PDDL translation] Former issues are fixed", "[PDDL translation]") { - // Check that translating domains without typing information works + plasp::output::Logger logger; + Context context(Parser(), logger); + + SECTION("translating domains without typing information works") { - auto description = Description::fromFile("data/issues/issue-4.pddl"); + auto description = Description::fromFile("data/issues/issue-4.pddl", context); const auto translator = TranslatorASP(description, description.context().logger.outputStream()); - ASSERT_NO_THROW(translator.translate()); + CHECK_NOTHROW(translator.translate()); } - // Check that translating the simple blocks world domain works + SECTION("translating the simple blocks world domain works") { - auto description = Description::fromFile("data/issues/issue-5.pddl"); + auto description = Description::fromFile("data/issues/issue-5.pddl", context); const auto translator = TranslatorASP(description, description.context().logger.outputStream()); - ASSERT_NO_THROW(translator.translate()); + CHECK_NOTHROW(translator.translate()); } } diff --git a/tests/TestSASParser.cpp b/tests/TestSASParser.cpp index 5994771..91ff682 100644 --- a/tests/TestSASParser.cpp +++ b/tests/TestSASParser.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -9,10 +9,10 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// -class SASParserTests : public ::testing::Test +class SASParserTestsFixture { protected: - SASParserTests() + SASParserTestsFixture() : m_blocksworldTestFile(readFile("data/blocksworld.sas")), m_cavedivingTestFile(readFile("data/cavediving.sas")), m_freecellTestFile(readFile("data/freecell.sas")), @@ -42,74 +42,74 @@ class SASParserTests : public ::testing::Test //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST_F(SASParserTests, ParseValidSASFile) +TEST_CASE_METHOD(SASParserTestsFixture, "[SAS parser] A valid SAS file is parsed correctly", "[SAS parser]") { try { const auto description = plasp::sas::Description::fromStream(m_philosophersTestFile); - ASSERT_FALSE(description.usesActionCosts()); + CHECK_FALSE(description.usesActionCosts()); - ASSERT_EQ(description.variables().size(), 37u); - ASSERT_EQ(description.variables()[0].axiomLayer(), -1); - ASSERT_EQ(description.variables()[0].values()[0].sign(), plasp::sas::Value::Sign::Positive); - ASSERT_EQ(description.variables()[0].values()[0].name(), "activate(philosopher-0, forks--pid-rfork)"); - ASSERT_EQ(description.variables()[36].axiomLayer(), -1); - ASSERT_EQ(description.variables()[36].values()[1].sign(), plasp::sas::Value::Sign::Negative); - ASSERT_EQ(description.variables()[36].values()[1].name(), "queue-tail-msg(forks-1-, fork)"); + REQUIRE(description.variables().size() == 37u); + CHECK(description.variables()[0].axiomLayer() == -1); + CHECK(description.variables()[0].values()[0].sign() == plasp::sas::Value::Sign::Positive); + CHECK(description.variables()[0].values()[0].name() == "activate(philosopher-0, forks--pid-rfork)"); + CHECK(description.variables()[36].axiomLayer() == -1); + CHECK(description.variables()[36].values()[1].sign() == plasp::sas::Value::Sign::Negative); + CHECK(description.variables()[36].values()[1].name() == "queue-tail-msg(forks-1-, fork)"); - ASSERT_EQ(description.mutexGroups().size(), 8u); - ASSERT_EQ(description.mutexGroups()[0].facts().size(), 9u); - ASSERT_EQ(&description.mutexGroups()[0].facts()[0].value(), &description.variables()[0].values()[0]); - ASSERT_EQ(description.mutexGroups()[7].facts().size(), 2u); - ASSERT_EQ(&description.mutexGroups()[7].facts()[1].value(), &description.variables()[34].values()[1]); + REQUIRE(description.mutexGroups().size() == 8u); + REQUIRE(description.mutexGroups()[0].facts().size() == 9u); + CHECK(&description.mutexGroups()[0].facts()[0].value() == &description.variables()[0].values()[0]); + REQUIRE(description.mutexGroups()[7].facts().size() == 2u); + CHECK(&description.mutexGroups()[7].facts()[1].value() == &description.variables()[34].values()[1]); - ASSERT_EQ(description.initialState().facts().size(), 37u); - ASSERT_EQ(&description.initialState().facts()[0].value(), &description.variables()[0].values()[8]); - ASSERT_EQ(&description.initialState().facts()[36].value(), &description.variables()[36].values()[1]); + REQUIRE(description.initialState().facts().size() == 37u); + CHECK(&description.initialState().facts()[0].value() == &description.variables()[0].values()[8]); + CHECK(&description.initialState().facts()[36].value() == &description.variables()[36].values()[1]); - ASSERT_EQ(description.goal().facts().size(), 2u); - ASSERT_EQ(&description.goal().facts()[0].value(), &description.variables()[6].values()[0]); - ASSERT_EQ(&description.goal().facts()[1].value(), &description.variables()[7].values()[0]); + REQUIRE(description.goal().facts().size() == 2u); + CHECK(&description.goal().facts()[0].value() == &description.variables()[6].values()[0]); + CHECK(&description.goal().facts()[1].value() == &description.variables()[7].values()[0]); - ASSERT_EQ(description.operators().size(), 34u); - ASSERT_EQ(description.operators()[0].predicate().name(), "activate-trans"); - ASSERT_EQ(description.operators()[0].predicate().arguments().size(), 5u); - ASSERT_EQ(description.operators()[0].predicate().arguments()[0], "philosopher-0"); - ASSERT_EQ(description.operators()[0].predicate().arguments()[4], "state-3"); - ASSERT_EQ(description.operators()[0].preconditions().size(), 3u); - ASSERT_EQ(&description.operators()[0].preconditions()[0].value(), &description.variables()[4].values()[4]); - ASSERT_EQ(&description.operators()[0].preconditions()[1].value(), &description.variables()[16].values()[1]); - ASSERT_EQ(&description.operators()[0].preconditions()[2].value(), &description.variables()[0].values()[8]); - ASSERT_EQ(description.operators()[0].effects().size(), 1u); - ASSERT_EQ(description.operators()[0].effects()[0].conditions().size(), 0u); - ASSERT_EQ(&description.operators()[0].effects()[0].postcondition().value(), &description.variables()[0].values()[0]); - ASSERT_EQ(description.operators()[33].predicate().name(), "queue-write"); - ASSERT_EQ(description.operators()[33].predicate().arguments().size(), 4u); - ASSERT_EQ(description.operators()[33].predicate().arguments()[0], "philosopher-1"); - ASSERT_EQ(description.operators()[33].predicate().arguments()[3], "fork"); - ASSERT_EQ(description.operators()[33].preconditions().size(), 2u); - ASSERT_EQ(&description.operators()[33].preconditions()[0].value(), &description.variables()[1].values()[3]); - ASSERT_EQ(&description.operators()[33].preconditions()[1].value(), &description.variables()[2].values()[2]); - ASSERT_EQ(description.operators()[33].effects().size(), 3u); - ASSERT_EQ(description.operators()[33].effects()[0].conditions().size(), 0u); - ASSERT_EQ(&description.operators()[33].effects()[0].postcondition().value(), &description.variables()[1].values()[7]); - ASSERT_EQ(&description.operators()[33].effects()[2].postcondition().value(), &description.variables()[35].values()[0]); + REQUIRE(description.operators().size() == 34u); + CHECK(description.operators()[0].predicate().name() == "activate-trans"); + REQUIRE(description.operators()[0].predicate().arguments().size() == 5u); + CHECK(description.operators()[0].predicate().arguments()[0] == "philosopher-0"); + CHECK(description.operators()[0].predicate().arguments()[4] == "state-3"); + REQUIRE(description.operators()[0].preconditions().size() == 3u); + CHECK(&description.operators()[0].preconditions()[0].value() == &description.variables()[4].values()[4]); + CHECK(&description.operators()[0].preconditions()[1].value() == &description.variables()[16].values()[1]); + CHECK(&description.operators()[0].preconditions()[2].value() == &description.variables()[0].values()[8]); + REQUIRE(description.operators()[0].effects().size() == 1u); + REQUIRE(description.operators()[0].effects()[0].conditions().size() == 0u); + CHECK(&description.operators()[0].effects()[0].postcondition().value() == &description.variables()[0].values()[0]); + CHECK(description.operators()[33].predicate().name() == "queue-write"); + REQUIRE(description.operators()[33].predicate().arguments().size() == 4u); + CHECK(description.operators()[33].predicate().arguments()[0] == "philosopher-1"); + CHECK(description.operators()[33].predicate().arguments()[3] == "fork"); + REQUIRE(description.operators()[33].preconditions().size() == 2u); + CHECK(&description.operators()[33].preconditions()[0].value() == &description.variables()[1].values()[3]); + CHECK(&description.operators()[33].preconditions()[1].value() == &description.variables()[2].values()[2]); + REQUIRE(description.operators()[33].effects().size() == 3u); + REQUIRE(description.operators()[33].effects()[0].conditions().size() == 0u); + CHECK(&description.operators()[33].effects()[0].postcondition().value() == &description.variables()[1].values()[7]); + CHECK(&description.operators()[33].effects()[2].postcondition().value() == &description.variables()[35].values()[0]); - ASSERT_EQ(description.axiomRules().size(), 33u); - ASSERT_EQ(description.axiomRules()[0].conditions().size(), 4u); - ASSERT_EQ(&description.axiomRules()[0].conditions()[0].value(), &description.variables()[0].values()[0]); - ASSERT_EQ(&description.axiomRules()[0].conditions()[2].value(), &description.variables()[27].values()[0]); - ASSERT_EQ(&description.axiomRules()[0].conditions()[3].value(), &description.variables()[8].values()[1]); - ASSERT_EQ(&description.axiomRules()[0].postcondition().value(), &description.variables()[8].values()[0]); - ASSERT_EQ(description.axiomRules()[32].conditions().size(), 2u); - ASSERT_EQ(&description.axiomRules()[32].conditions()[0].value(), &description.variables()[15].values()[0]); - ASSERT_EQ(&description.axiomRules()[32].conditions()[1].value(), &description.variables()[25].values()[0]); - ASSERT_EQ(&description.axiomRules()[32].postcondition().value(), &description.variables()[25].values()[1]); + REQUIRE(description.axiomRules().size() == 33u); + REQUIRE(description.axiomRules()[0].conditions().size() == 4u); + CHECK(&description.axiomRules()[0].conditions()[0].value() == &description.variables()[0].values()[0]); + CHECK(&description.axiomRules()[0].conditions()[2].value() == &description.variables()[27].values()[0]); + CHECK(&description.axiomRules()[0].conditions()[3].value() == &description.variables()[8].values()[1]); + CHECK(&description.axiomRules()[0].postcondition().value() == &description.variables()[8].values()[0]); + REQUIRE(description.axiomRules()[32].conditions().size() == 2u); + CHECK(&description.axiomRules()[32].conditions()[0].value() == &description.variables()[15].values()[0]); + CHECK(&description.axiomRules()[32].conditions()[1].value() == &description.variables()[25].values()[0]); + CHECK(&description.axiomRules()[32].postcondition().value() == &description.variables()[25].values()[1]); } catch (const std::exception &e) { - FAIL() << e.what(); + FAIL(e.what()); } // TODO: add whitespace test @@ -117,71 +117,71 @@ TEST_F(SASParserTests, ParseValidSASFile) //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST_F(SASParserTests, RemoveTrailingParentheses) +TEST_CASE_METHOD(SASParserTestsFixture, "[SAS parser] Trailing empty parentheses are removed", "[SAS parser]") { try { const auto description = plasp::sas::Description::fromStream(m_blocksworldTestFile); - ASSERT_EQ(description.variables()[4].values()[0].name(), "handempty"); - ASSERT_EQ(description.variables()[5].values()[0].name(), "holding(a)"); + CHECK(description.variables()[4].values()[0].name() == "handempty"); + CHECK(description.variables()[5].values()[0].name() == "holding(a)"); } catch (const std::exception &e) { - FAIL() << e.what(); + FAIL(e.what()); } } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST_F(SASParserTests, ParseNoneValue) +TEST_CASE_METHOD(SASParserTestsFixture, "[SAS parser] “none” values are correctly parsed", "[SAS parser]") { try { const auto description = plasp::sas::Description::fromStream(m_freecellTestFile); // TODO: compare by identity, not value - ASSERT_EQ(description.variables()[0].values()[3], plasp::sas::Value::None); - ASSERT_EQ(description.variables()[5].values()[6], plasp::sas::Value::None); + CHECK(description.variables()[0].values()[3] == plasp::sas::Value::None); + CHECK(description.variables()[5].values()[6] == plasp::sas::Value::None); } catch (const std::exception &e) { - FAIL() << e.what(); + FAIL(e.what()); } } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST_F(SASParserTests, ParseRequirements) +TEST_CASE_METHOD(SASParserTestsFixture, "[SAS parser] SAS requirements are parsed correctly", "[SAS parser]") { try { const auto description = plasp::sas::Description::fromStream(m_cavedivingTestFile); - ASSERT_TRUE(description.usesActionCosts()); - ASSERT_TRUE(description.usesConditionalEffects()); - ASSERT_FALSE(description.usesAxiomRules()); + CHECK(description.usesActionCosts()); + CHECK(description.usesConditionalEffects()); + CHECK_FALSE(description.usesAxiomRules()); - ASSERT_EQ(description.operators().size(), 496u); + REQUIRE(description.operators().size() == 496u); - ASSERT_EQ(description.operators()[0].costs(), 1u); - ASSERT_EQ(description.operators()[172].costs(), 10u); - ASSERT_EQ(description.operators()[173].costs(), 63u); + CHECK(description.operators()[0].costs() == 1u); + CHECK(description.operators()[172].costs() == 10u); + CHECK(description.operators()[173].costs() == 63u); - ASSERT_EQ(description.operators()[172].effects().size(), 3u); - ASSERT_EQ(description.operators()[172].effects()[1].conditions().size(), 1u); - ASSERT_EQ(&description.operators()[172].effects()[1].conditions()[0].value(), &description.variables()[1].values()[4]); + REQUIRE(description.operators()[172].effects().size() == 3u); + REQUIRE(description.operators()[172].effects()[1].conditions().size() == 1u); + CHECK(&description.operators()[172].effects()[1].conditions()[0].value() == &description.variables()[1].values()[4]); } catch (const std::exception &e) { - FAIL() << e.what(); + FAIL(e.what()); } } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST_F(SASParserTests, CheckIssues) +TEST_CASE("[SAS parser] Former issues are fixed", "[SAS parser]") { // Check issue where unexpected whitespaces in SAS files led to a parsing error - ASSERT_NO_THROW(plasp::sas::Description::fromFile("data/issues/issue-6.sas")); + CHECK_NOTHROW(plasp::sas::Description::fromFile("data/issues/issue-6.sas")); } diff --git a/tests/TestUtils.cpp b/tests/TestUtils.cpp index a363bef..20d7eeb 100644 --- a/tests/TestUtils.cpp +++ b/tests/TestUtils.cpp @@ -1,332 +1,332 @@ -#include +#include -#include -#include +#include +#include //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(UtilsTests, ParserParse) +TEST_CASE("[parser] Simple strings are parsed correctly", "[parser]") { std::stringstream s(" identifier 5 \n-51\t 0 1 100 200 -300 -400"); - plasp::utils::Parser<> p("input", s); + plasp::input::Parser<> p("input", s); - ASSERT_EQ(p.parse(), "identifier"); - ASSERT_EQ(p.parse(), 5u); - ASSERT_EQ(p.parse(), -51); - ASSERT_EQ(p.parse(), false); - ASSERT_EQ(p.parse(), true); + REQUIRE(p.parse() == "identifier"); + REQUIRE(p.parse() == 5u); + REQUIRE(p.parse() == -51); + REQUIRE(p.parse() == false); + REQUIRE(p.parse() == true); - ASSERT_EQ(p.parse(), 100); - ASSERT_EQ(p.parse(), 200u); - ASSERT_EQ(p.parse(), -300); - ASSERT_THROW(p.parse(), plasp::utils::ParserException); + REQUIRE(p.parse() == 100); + REQUIRE(p.parse() == 200u); + REQUIRE(p.parse() == -300); + REQUIRE_THROWS_AS(p.parse(), plasp::input::ParserException); } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(UtilsTests, ParserExpect) +TEST_CASE("[parser] Parsing exceptions are correctly reported", "[parser]") { std::stringstream s(" identifier 5 \n-51\t 0 1 100 200 -300 -400"); - plasp::utils::Parser<> p("input", s); + plasp::input::Parser<> p("input", s); - ASSERT_NO_THROW(p.expect("identifier")); - ASSERT_NO_THROW(p.expect(5u)); - ASSERT_NO_THROW(p.expect(-51)); - ASSERT_NO_THROW(p.expect(false)); - ASSERT_NO_THROW(p.expect(true)); + REQUIRE_NOTHROW(p.expect("identifier")); + REQUIRE_NOTHROW(p.expect(5u)); + REQUIRE_NOTHROW(p.expect(-51)); + REQUIRE_NOTHROW(p.expect(false)); + REQUIRE_NOTHROW(p.expect(true)); - ASSERT_NO_THROW(p.expect(100)); - ASSERT_NO_THROW(p.expect(200u)); - ASSERT_NO_THROW(p.expect(-300)); - ASSERT_THROW(p.expect(-400), plasp::utils::ParserException); + REQUIRE_NOTHROW(p.expect(100)); + REQUIRE_NOTHROW(p.expect(200u)); + REQUIRE_NOTHROW(p.expect(-300)); + REQUIRE_THROWS_AS(p.expect(-400), plasp::input::ParserException); p.seek(0); - ASSERT_THROW(p.expect("error"), plasp::utils::ParserException); + REQUIRE_THROWS_AS(p.expect("error"), plasp::input::ParserException); p.seek(14); - ASSERT_THROW(p.expect(6u), plasp::utils::ParserException); + REQUIRE_THROWS_AS(p.expect(6u), plasp::input::ParserException); p.seek(17); - ASSERT_THROW(p.expect(-50), plasp::utils::ParserException); + REQUIRE_THROWS_AS(p.expect(-50), plasp::input::ParserException); p.seek(24); - ASSERT_THROW(p.expect(true), plasp::utils::ParserException); + REQUIRE_THROWS_AS(p.expect(true), plasp::input::ParserException); p.seek(26); - ASSERT_THROW(p.expect(false), plasp::utils::ParserException); + REQUIRE_THROWS_AS(p.expect(false), plasp::input::ParserException); p.seek(28); - ASSERT_THROW(p.expect(101), plasp::utils::ParserException); + REQUIRE_THROWS_AS(p.expect(101), plasp::input::ParserException); p.seek(31); - ASSERT_THROW(p.expect(201), plasp::utils::ParserException); + REQUIRE_THROWS_AS(p.expect(201), plasp::input::ParserException); p.seek(34); - ASSERT_THROW(p.expect(-299), plasp::utils::ParserException); + REQUIRE_THROWS_AS(p.expect(-299), plasp::input::ParserException); } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(UtilsTests, ParserTest) +TEST_CASE("[parser] While parsing, the cursor position is as expected", "[parser]") { std::stringstream s(" identifier 5 \n-51\t 0 1"); - plasp::utils::Parser<> p("input", s); + plasp::input::Parser<> p("input", s); - plasp::utils::Parser<>::Position pos; + plasp::input::Parser<>::Position pos; pos = p.position(); - ASSERT_EQ(p.testAndReturn("error"), false); - ASSERT_EQ(p.position(), pos); - ASSERT_EQ(p.testAndReturn("identifier"), true); - ASSERT_EQ(p.position(), pos); - ASSERT_EQ(p.testAndSkip("error"), false); - ASSERT_EQ(p.position(), pos); - ASSERT_EQ(p.testAndSkip("identifier"), true); - ASSERT_EQ(p.position(), 12); + REQUIRE(p.testAndReturn("error") == false); + REQUIRE(p.position() == pos); + REQUIRE(p.testAndReturn("identifier") == true); + REQUIRE(p.position() == pos); + REQUIRE(p.testAndSkip("error") == false); + REQUIRE(p.position() == pos); + REQUIRE(p.testAndSkip("identifier") == true); + REQUIRE(p.position() == 12); pos = p.position(); - ASSERT_EQ(p.testAndReturn(6u), false); - ASSERT_EQ(p.position(), pos); - ASSERT_EQ(p.testAndReturn(5u), true); - ASSERT_EQ(p.position(), pos); - ASSERT_EQ(p.testAndSkip(6u), false); - ASSERT_EQ(p.position(), pos); - ASSERT_EQ(p.testAndSkip(5u), true); - ASSERT_EQ(p.position(), 15); + REQUIRE(p.testAndReturn(6u) == false); + REQUIRE(p.position() == pos); + REQUIRE(p.testAndReturn(5u) == true); + REQUIRE(p.position() == pos); + REQUIRE(p.testAndSkip(6u) == false); + REQUIRE(p.position() == pos); + REQUIRE(p.testAndSkip(5u) == true); + REQUIRE(p.position() == 15); pos = p.position(); - ASSERT_EQ(p.testAndReturn(-50), false); - ASSERT_EQ(p.position(), pos); - ASSERT_EQ(p.testAndReturn(-51), true); - ASSERT_EQ(p.position(), pos); - ASSERT_EQ(p.testAndSkip(-50), false); - ASSERT_EQ(p.position(), pos); - ASSERT_EQ(p.testAndSkip(-51), true); - ASSERT_EQ(p.position(), 22); + REQUIRE(p.testAndReturn(-50) == false); + REQUIRE(p.position() == pos); + REQUIRE(p.testAndReturn(-51) == true); + REQUIRE(p.position() == pos); + REQUIRE(p.testAndSkip(-50) == false); + REQUIRE(p.position() == pos); + REQUIRE(p.testAndSkip(-51) == true); + REQUIRE(p.position() == 22); pos = p.position(); - ASSERT_EQ(p.testAndReturn(true), false); - ASSERT_EQ(p.position(), pos); - ASSERT_EQ(p.testAndReturn(false), true); - ASSERT_EQ(p.position(), pos); - ASSERT_EQ(p.testAndSkip(true), false); - ASSERT_EQ(p.position(), pos); - ASSERT_EQ(p.testAndSkip(false), true); - ASSERT_EQ(p.position(), 25); + REQUIRE(p.testAndReturn(true) == false); + REQUIRE(p.position() == pos); + REQUIRE(p.testAndReturn(false) == true); + REQUIRE(p.position() == pos); + REQUIRE(p.testAndSkip(true) == false); + REQUIRE(p.position() == pos); + REQUIRE(p.testAndSkip(false) == true); + REQUIRE(p.position() == 25); pos = p.position(); - ASSERT_EQ(p.testAndReturn(false), false); - ASSERT_EQ(p.position(), pos); - ASSERT_EQ(p.testAndReturn(true), true); - ASSERT_EQ(p.position(), pos); - ASSERT_EQ(p.testAndSkip(false), false); - ASSERT_EQ(p.position(), pos); - ASSERT_EQ(p.testAndSkip(true), true); - ASSERT_EQ(p.position(), 27); + REQUIRE(p.testAndReturn(false) == false); + REQUIRE(p.position() == pos); + REQUIRE(p.testAndReturn(true) == true); + REQUIRE(p.position() == pos); + REQUIRE(p.testAndSkip(false) == false); + REQUIRE(p.position() == pos); + REQUIRE(p.testAndSkip(true) == true); + REQUIRE(p.position() == 27); } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(UtilsTests, ParseEndOfFile) +TEST_CASE("[parser] The end of the input stream is correctly handled", "[parser]") { std::stringstream s1("test"); - plasp::utils::Parser<> p1("input", s1); + plasp::input::Parser<> p1("input", s1); - ASSERT_NO_THROW(p1.expect("test")); - ASSERT_THROW(p1.parse(), plasp::utils::ParserException); + REQUIRE_NOTHROW(p1.expect("test")); + REQUIRE_THROWS_AS(p1.parse(), plasp::input::ParserException); std::stringstream s2("test1 test2 test3"); - plasp::utils::Parser<> p2("input", s2); + plasp::input::Parser<> p2("input", s2); - ASSERT_NO_THROW(p2.expect("test1")); - ASSERT_NO_THROW(p2.expect("test2")); - ASSERT_NO_THROW(p2.expect("test3")); - ASSERT_THROW(p2.parse(), plasp::utils::ParserException); + REQUIRE_NOTHROW(p2.expect("test1")); + REQUIRE_NOTHROW(p2.expect("test2")); + REQUIRE_NOTHROW(p2.expect("test3")); + REQUIRE_THROWS_AS(p2.parse(), plasp::input::ParserException); std::stringstream s3("-127"); - plasp::utils::Parser<> p3("input", s3); + plasp::input::Parser<> p3("input", s3); p3.expect(-127); - ASSERT_THROW(p3.parse(), plasp::utils::ParserException); + REQUIRE_THROWS_AS(p3.parse(), plasp::input::ParserException); std::stringstream s4("128 -1023 -4095"); - plasp::utils::Parser<> p4("input", s4); + plasp::input::Parser<> p4("input", s4); - ASSERT_NO_THROW(p4.expect(128)); - ASSERT_NO_THROW(p4.expect(-1023)); - ASSERT_NO_THROW(p4.expect(-4095)); - ASSERT_THROW(p4.parse(), plasp::utils::ParserException); + REQUIRE_NOTHROW(p4.expect(128)); + REQUIRE_NOTHROW(p4.expect(-1023)); + REQUIRE_NOTHROW(p4.expect(-4095)); + REQUIRE_THROWS_AS(p4.parse(), plasp::input::ParserException); std::stringstream s5("0"); - plasp::utils::Parser<> p5("input", s5); + plasp::input::Parser<> p5("input", s5); p5.expect(false); - ASSERT_THROW(p5.parse(), plasp::utils::ParserException); + REQUIRE_THROWS_AS(p5.parse(), plasp::input::ParserException); std::stringstream s6("0 1 0"); - plasp::utils::Parser<> p6("input", s6); + plasp::input::Parser<> p6("input", s6); - ASSERT_NO_THROW(p6.expect(false)); - ASSERT_NO_THROW(p6.expect(true)); - ASSERT_NO_THROW(p6.expect(false)); - ASSERT_THROW(p6.parse(), plasp::utils::ParserException); + REQUIRE_NOTHROW(p6.expect(false)); + REQUIRE_NOTHROW(p6.expect(true)); + REQUIRE_NOTHROW(p6.expect(false)); + REQUIRE_THROWS_AS(p6.parse(), plasp::input::ParserException); } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(UtilsTests, ParserPosition) +TEST_CASE("[parser] While parsing, the cursor location is as expcected", "[parser]") { std::stringstream s("123 \n4\ntest1\n test2\ntest3 \ntest4\n\n\n\n"); - plasp::utils::Parser<> p("input", s); + plasp::input::Parser<> p("input", s); const auto startPosition = p.position(); - plasp::utils::StreamCoordinate c; + plasp::input::Location l; - c = p.coordinate(); - ASSERT_EQ(c.row, 1u); - ASSERT_EQ(c.column, 1u); - ASSERT_EQ(p.currentCharacter(), '1'); + l = p.location(); + REQUIRE(l.rowStart == 1u); + REQUIRE(l.columnStart == 1u); + REQUIRE(p.currentCharacter() == '1'); - ASSERT_NO_THROW(p.advance()); + REQUIRE_NOTHROW(p.advance()); - c = p.coordinate(); - ASSERT_EQ(c.row, 1u); - ASSERT_EQ(c.column, 2u); - ASSERT_EQ(p.currentCharacter(), '2'); + l = p.location(); + REQUIRE(l.rowStart == 1u); + REQUIRE(l.columnStart == 2u); + REQUIRE(p.currentCharacter() == '2'); - ASSERT_NO_THROW(p.advance()); + REQUIRE_NOTHROW(p.advance()); - c = p.coordinate(); - ASSERT_EQ(c.row, 1u); - ASSERT_EQ(c.column, 3u); - ASSERT_EQ(p.currentCharacter(), '3'); + l = p.location(); + REQUIRE(l.rowStart == 1u); + REQUIRE(l.columnStart == 3u); + REQUIRE(p.currentCharacter() == '3'); - ASSERT_NO_THROW(p.advance()); + REQUIRE_NOTHROW(p.advance()); - c = p.coordinate(); - ASSERT_EQ(c.row, 1u); - ASSERT_EQ(c.column, 4u); - ASSERT_EQ(p.currentCharacter(), ' '); + l = p.location(); + REQUIRE(l.rowStart == 1u); + REQUIRE(l.columnStart == 4u); + REQUIRE(p.currentCharacter() == ' '); - ASSERT_NO_THROW(p.advance()); + REQUIRE_NOTHROW(p.advance()); - c = p.coordinate(); - ASSERT_EQ(c.row, 1u); - ASSERT_EQ(c.column, 5u); - ASSERT_EQ(p.currentCharacter(), '\n'); + l = p.location(); + REQUIRE(l.rowStart == 1u); + REQUIRE(l.columnStart == 5u); + REQUIRE(p.currentCharacter() == '\n'); - ASSERT_NO_THROW(p.advance()); + REQUIRE_NOTHROW(p.advance()); - c = p.coordinate(); - ASSERT_EQ(c.row, 2u); - ASSERT_EQ(c.column, 1u); - ASSERT_EQ(p.currentCharacter(), '4'); + l = p.location(); + REQUIRE(l.rowStart == 2u); + REQUIRE(l.columnStart == 1u); + REQUIRE(p.currentCharacter() == '4'); - ASSERT_NO_THROW(p.advance()); + REQUIRE_NOTHROW(p.advance()); - ASSERT_NO_THROW(p.expect("test1")); + REQUIRE_NOTHROW(p.expect("test1")); - c = p.coordinate(); - ASSERT_EQ(c.row, 3u); - ASSERT_EQ(c.column, 6u); + l = p.location(); + REQUIRE(l.rowStart == 3u); + REQUIRE(l.columnStart == 6u); - ASSERT_NO_THROW(p.expect("test2")); + REQUIRE_NOTHROW(p.expect("test2")); - c = p.coordinate(); - ASSERT_EQ(c.row, 4u); - ASSERT_EQ(c.column, 7u); + l = p.location(); + REQUIRE(l.rowStart == 4u); + REQUIRE(l.columnStart == 7u); - ASSERT_NO_THROW(p.expect("test3")); + REQUIRE_NOTHROW(p.expect("test3")); - c = p.coordinate(); - ASSERT_EQ(c.row, 5u); - ASSERT_EQ(c.column, 6u); + l = p.location(); + REQUIRE(l.rowStart == 5u); + REQUIRE(l.columnStart == 6u); - ASSERT_NO_THROW(p.skipLine()); + REQUIRE_NOTHROW(p.skipLine()); - c = p.coordinate(); - ASSERT_EQ(c.row, 6u); - ASSERT_EQ(c.column, 1u); + l = p.location(); + REQUIRE(l.rowStart == 6u); + REQUIRE(l.columnStart == 1u); - ASSERT_NO_THROW(p.skipLine()); + REQUIRE_NOTHROW(p.skipLine()); - c = p.coordinate(); - ASSERT_EQ(c.row, 7u); - ASSERT_EQ(c.column, 1u); + l = p.location(); + REQUIRE(l.rowStart == 7u); + REQUIRE(l.columnStart == 1u); - ASSERT_NO_THROW(p.skipWhiteSpace()); + REQUIRE_NOTHROW(p.skipWhiteSpace()); - c = p.coordinate(); - ASSERT_EQ(c.row, 10u); - ASSERT_EQ(c.column, 1u); - ASSERT_TRUE(p.atEnd()); + l = p.location(); + REQUIRE(l.rowStart == 10u); + REQUIRE(l.columnStart == 1u); + REQUIRE(p.atEnd()); p.reset(); - ASSERT_EQ(p.position(), startPosition); - ASSERT_FALSE(p.atEnd()); + REQUIRE(p.position() == startPosition); + REQUIRE_FALSE(p.atEnd()); for (size_t i = 0; i < 5; i++) p.advance(); - ASSERT_EQ(p.position(), static_cast(5)); + REQUIRE(p.position() == static_cast(5)); p.seek(static_cast(7)); - ASSERT_EQ(p.position(), static_cast(7)); + REQUIRE(p.position() == static_cast(7)); - ASSERT_NO_THROW(p.expect("test1")); + REQUIRE_NOTHROW(p.expect("test1")); // TODO: test parser with multiple sections } //////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(UtilsTests, ParserRemoveComments) +TEST_CASE("[parser] Comments are correctly removed", "[parser]") { std::stringstream s1("; comment at beginning\ntest1; comment in between\ntest2; comment at end"); - plasp::utils::Parser<> p1("input", s1); + plasp::input::Parser<> p1("input", s1); p1.removeComments(";", "\n", false); - plasp::utils::StreamCoordinate c; + plasp::input::Location l; - ASSERT_NO_THROW(p1.expect("test1")); + REQUIRE_NOTHROW(p1.expect("test1")); - c = p1.coordinate(); - ASSERT_EQ(c.row, 2u); - ASSERT_EQ(c.column, 6u); + l = p1.location(); + REQUIRE(l.rowStart == 2u); + REQUIRE(l.columnStart == 6u); - ASSERT_NO_THROW(p1.expect("test2")); + REQUIRE_NOTHROW(p1.expect("test2")); - c = p1.coordinate(); - ASSERT_EQ(c.row, 3u); - ASSERT_EQ(c.column, 6u); + l = p1.location(); + REQUIRE(l.rowStart == 3u); + REQUIRE(l.columnStart == 6u); p1.skipWhiteSpace(); - ASSERT_TRUE(p1.atEnd()); + REQUIRE(p1.atEnd()); std::stringstream s2("test;"); - plasp::utils::Parser<> p2("input", s2); + plasp::input::Parser<> p2("input", s2); p2.removeComments(";", "\n", false); - ASSERT_NO_THROW(p2.expect("test")); + REQUIRE_NOTHROW(p2.expect("test")); p2.skipWhiteSpace(); - ASSERT_TRUE(p2.atEnd()); + REQUIRE(p2.atEnd()); std::stringstream s3("/* comment at start */ test1 /* comment in between */ test2 /*"); - plasp::utils::Parser<> p3("input", s3); + plasp::input::Parser<> p3("input", s3); p3.removeComments("/*", "*/", true); - ASSERT_NO_THROW(p3.expect("test1")); - ASSERT_NO_THROW(p3.expect("test2")); + REQUIRE_NOTHROW(p3.expect("test1")); + REQUIRE_NOTHROW(p3.expect("test2")); p3.skipWhiteSpace(); - ASSERT_TRUE(p3.atEnd()); + REQUIRE(p3.atEnd()); } diff --git a/tests/googletest b/tests/googletest deleted file mode 160000 index c994585..0000000 --- a/tests/googletest +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c99458533a9b4c743ed51537e25989ea55944908 diff --git a/tests/main.cpp b/tests/main.cpp new file mode 100644 index 0000000..b3143fb --- /dev/null +++ b/tests/main.cpp @@ -0,0 +1,2 @@ +#define CATCH_CONFIG_MAIN +#include