Compare commits
256 Commits
Author | SHA1 | Date | |
---|---|---|---|
9af383d2f6 | |||
d3039d55e5 | |||
6b5c8df03a | |||
8084fe5574 | |||
3d661cd1f4 | |||
853d7471c2 | |||
0a205680fe | |||
52fee6a4c1 | |||
fcdd3bba2b | |||
b491efa9f4 | |||
401cf79cf6 | |||
44a20ca7e3 | |||
5bda1c2245 | |||
eb3d91f085 | |||
aff396d919 | |||
f7cd24b67a | |||
1e21457efb | |||
583ec78eef | |||
9969281b11 | |||
6fec1cc409 | |||
2984da773d | |||
1b83708a6d | |||
0de2489440 | |||
fd5416c94e | |||
48137ec24d | |||
febef4bed4 | |||
b599670572 | |||
57e9de6b05 | |||
9679706a08 | |||
777c9839a1 | |||
a6c9434590 | |||
fd77b65226 | |||
a23063fd4f | |||
a7cf696357 | |||
94d448d438 | |||
c62f3f88f1 | |||
39a32a6e0a | |||
342a346fce | |||
e0dd9833a3 | |||
591d3fcafd | |||
22f294493e | |||
5d3496fa41 | |||
4b500e4bf6 | |||
da85e5dd9b | |||
2b55d156ae | |||
f24491cd5a | |||
268bee3c5f | |||
5c3ea28e48 | |||
fdbcb261df | |||
2c3481d027 | |||
1c2ad0ceec | |||
7899d3e262 | |||
6b88cb7926 | |||
421125fee6 | |||
8563011939 | |||
e07672ffe6 | |||
23f6f9b26b | |||
e9c464b319 | |||
d3dc9101dd | |||
e018cdbc91 | |||
e2b8fd2880 | |||
680206b40b | |||
1c8af793c2 | |||
46351b2fe7 | |||
30cfa1b45e | |||
0756d63769 | |||
87ca54a253 | |||
9c2f49e4a0 | |||
49002ac52d | |||
b70e62ff3b | |||
046f803538 | |||
639b7646c9 | |||
89bb54a3ec | |||
979d9509c1 | |||
e9d48bcb7d | |||
318bd8297c | |||
0513b3aa0c | |||
458dbd723c | |||
8f0f4bfa65 | |||
da71d4947b | |||
6a83147ac0 | |||
f6cfc55e21 | |||
34a413cf05 | |||
854ade5fa9 | |||
be09230410 | |||
20b40d3e1c | |||
9f0e784a4a | |||
168fcc874e | |||
d446c192cf | |||
eb5a120286 | |||
2e1a011dcf | |||
8ef874eb22 | |||
c6dc84f27f | |||
8bb25e9b90 | |||
c6bdfe3f38 | |||
d1063b345d | |||
dea879199a | |||
9a034cb556 | |||
5cd22d284b | |||
f8fc1865a2 | |||
85444f235b | |||
15061f75a9 | |||
d138e869fc | |||
23170e170a | |||
156dfd88c2 | |||
730a9b7e63 | |||
3041b6a278 | |||
2da5be548a | |||
6f1b38cdb7 | |||
a8e4ef7234 | |||
c7405e054f | |||
9506dcb31e | |||
04aac10f1d | |||
bbb6379907 | |||
26d7e216a6 | |||
d629f50661 | |||
2245422d0f | |||
87889f5efe | |||
fb15a131ac | |||
8428c20bd4 | |||
ff7a6b8c8f | |||
d92a3e9239 | |||
d23ec14e9d | |||
ad23c89266 | |||
1c8958ad9d | |||
c99b7018c6 | |||
f2089f48b8 | |||
75e51c856e | |||
e60af33f75 | |||
993d14d409 | |||
bf0e636d57 | |||
374ac3b07f | |||
183b0c954e | |||
42559fd601 | |||
069ad4ca99 | |||
8db4b5a53e | |||
32883910bb | |||
9b3f78559e | |||
7bd2782fc8 | |||
75fbb5fb48 | |||
af2f9290c6 | |||
31fb8ba79b | |||
ee9626e4d2 | |||
9360f4295a | |||
abfa3b3ca1 | |||
a1b93624d6 | |||
69ff84eecc | |||
78889e18c6 | |||
fa178d5ee1 | |||
eea3272c56 | |||
27e76fc035 | |||
188165bc4d | |||
e6ddad5960 | |||
4228ca01dc | |||
64190ba55a | |||
c489c7fd5a | |||
acc063822e | |||
b612122180 | |||
d5fa00a4a4 | |||
e607ca4e8e | |||
d64c68f754 | |||
e5bf7d754f | |||
0e739755b7 | |||
f8eab1cbb6 | |||
0f2c81f894 | |||
e481732fae | |||
ee597c805e | |||
e561c55f73 | |||
2870bc6434 | |||
7e60631840 | |||
f2a1528ea9 | |||
21af7e9983 | |||
4ae37603f4 | |||
30b4a1f614 | |||
2797b58646 | |||
837612bb8d | |||
813fecbf15 | |||
a776fc9e06 | |||
08eb14e400 | |||
60c072a2b3 | |||
feedb95295 | |||
c93661f44e | |||
daa063c338 | |||
5abf1f8a84 | |||
133aa051eb | |||
d334b4150b | |||
36e28994ee | |||
01908c52f8 | |||
f9463d629a | |||
50315f5fae | |||
8817a3f226 | |||
fcde9c9b6b | |||
fb5a5a71a5 | |||
8134c6af80 | |||
7271a5e52b | |||
7baf15d9f0 | |||
d070b5be9e | |||
63d74e3524 | |||
a07019801c | |||
97ab22461c | |||
138db460a9 | |||
a9c0431ded | |||
7e4a05e1db | |||
0a4541a401 | |||
79773ba634 | |||
b249e1cbf8 | |||
25cf7c8ae8 | |||
3c97ced486 | |||
44482ae438 | |||
f597b3ab80 | |||
b8223b42bd | |||
ced1fd0038 | |||
2654a6ff23 | |||
5f763e90fc | |||
cf1c66a085 | |||
1395b62e60 | |||
85da5024ea | |||
a989f5f86e | |||
1c4c035acc | |||
d26ff2df77 | |||
5c37026ec7 | |||
8aa419b5c2 | |||
c191b418f2 | |||
0eb2714c9e | |||
0b33ac0e7d | |||
f55e366b17 | |||
b89b1708c3 | |||
f9c5a830e1 | |||
348bd98de8 | |||
4d984d32c3 | |||
8d879344f2 | |||
40547691a0 | |||
8f705b0737 | |||
67c9e2148d | |||
42fda5925d | |||
2c564f47d3 | |||
b4bc347006 | |||
f81fd1a1b4 | |||
a1b334a302 | |||
ff420fbe57 | |||
07eb23b312 | |||
6017cfe3d5 | |||
8eb0a4847f | |||
47f269782e | |||
d9a40af3f0 | |||
2281967176 | |||
6b38b55c58 | |||
12ffbb4d80 | |||
045239b620 | |||
dda81e9011 | |||
98a15bbf8e | |||
7a8b562173 | |||
0cbb3453bd | |||
062a04233f | |||
75c841e3c5 | |||
441b8b0154 |
5
.gitattributes
vendored
5
.gitattributes
vendored
@@ -1 +1,6 @@
|
|||||||
|
.gitignore export-ignore
|
||||||
|
.gitattributes export-ignore
|
||||||
|
.gitmodules export-ignore
|
||||||
|
.travis.yml export-ignore
|
||||||
|
|
||||||
tests/data/* linguist-documentation
|
tests/data/* linguist-documentation
|
||||||
|
10
.travis.yml
10
.travis.yml
@@ -11,11 +11,15 @@ matrix:
|
|||||||
- boost-latest
|
- boost-latest
|
||||||
packages:
|
packages:
|
||||||
- g++-5
|
- g++-5
|
||||||
- libboost1.55-all-dev
|
- libboost-program-options1.55-dev
|
||||||
- libgtest-dev
|
- libboost-iostreams1.55-dev
|
||||||
|
- libboost-system1.55-dev
|
||||||
|
- libboost-filesystem1.55-dev
|
||||||
env: COMPILER=g++-5
|
env: COMPILER=g++-5
|
||||||
script:
|
script:
|
||||||
|
- git submodule init
|
||||||
|
- git submodule update
|
||||||
- mkdir build
|
- mkdir build
|
||||||
- cd build
|
- cd build
|
||||||
- cmake .. -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTS=ON -DCMAKE_CXX_COMPILER=$COMPILER
|
- cmake .. -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTS=ON -DCMAKE_CXX_COMPILER=$COMPILER
|
||||||
- make && make run-tests
|
- make -j3 && make -j3 run-tests
|
||||||
|
25
CHANGELOG.md
Normal file
25
CHANGELOG.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# Change Log
|
||||||
|
|
||||||
|
## 3.0.1 (2016-06-14)
|
||||||
|
|
||||||
|
Features:
|
||||||
|
|
||||||
|
* basic support for parsing PDDL 3.1 domains and problems
|
||||||
|
* limited support for translating PDDL 3.1 domains and problems to ASP facts
|
||||||
|
* automatic language detection for PDDL and SAS
|
||||||
|
* supports input from `std::cin`
|
||||||
|
* supports colorized output
|
||||||
|
* new command-line option `--language` to explicitly specify input language
|
||||||
|
* new command-line option `--warning-level` to treat warnings as errors or to ignore warnings
|
||||||
|
* new command-line option `--color` to autodetect, enable, or disable color output
|
||||||
|
|
||||||
|
Bug Fixes:
|
||||||
|
|
||||||
|
* fixes bug in translation of SAS axiom rules
|
||||||
|
|
||||||
|
## 3.0.0 (2016-05-24)
|
||||||
|
|
||||||
|
Features:
|
||||||
|
|
||||||
|
* parses [SAS](http://www.fast-downward.org/TranslatorOutputFormat) files created with [Fast Downward](http://www.fast-downward.org/)
|
||||||
|
* experimental translation from SAS to ASP facts
|
@@ -3,11 +3,11 @@ project(plasp CXX)
|
|||||||
|
|
||||||
find_package(Boost 1.55.0 COMPONENTS program_options iostreams system filesystem REQUIRED)
|
find_package(Boost 1.55.0 COMPONENTS program_options iostreams system filesystem REQUIRED)
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "-Wall -Wpedantic")
|
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wpedantic")
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "-g")
|
set(CMAKE_CXX_FLAGS_DEBUG "-g")
|
||||||
add_definitions(-std=c++14)
|
add_definitions(-std=c++14)
|
||||||
|
|
||||||
option(BUILD_TESTS "Build unit tests" OFF)
|
option(BUILD_TESTS "Build unit tests" ON)
|
||||||
|
|
||||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
The MIT License (MIT)
|
# The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2016 Patrick Lühne
|
Copyright © 2016 Patrick Lühne
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
68
README.md
68
README.md
@@ -1,39 +1,65 @@
|
|||||||
# plasp—Translate PDDL to ASP
|
# plasp—Translate PDDL to ASP
|
||||||
|
|
||||||
[](https://travis-ci.org/potassco/plasp)
|
[](https://github.com/potassco/plasp/releases)
|
||||||
|
[)](https://travis-ci.org/potassco/plasp?branch=master)
|
||||||
|
[)](https://travis-ci.org/potassco/plasp?branch=develop)
|
||||||
|
|
||||||
`plasp` 3 is in early development and not intended for productive use yet.
|
`plasp` 3 is in early development and not intended for productive use yet.
|
||||||
|
|
||||||
As of now, `plasp` 3 experimentally supports the full [SAS Format](http://www.fast-downward.org/TranslatorOutputFormat) (as of version 3) used by [Fast Downward](http://www.fast-downward.org/).
|
`plasp` 3 translates planning problem instances to ASP facts.
|
||||||
|
`plasp` 3 supports the input languages [PDDL](https://helios.hud.ac.uk/scommv/IPC-14/software.html) (only basic features currently) and the [SAS](http://www.fast-downward.org/TranslatorOutputFormat) (full support of the current version 3), which is used by [Fast Downward](http://www.fast-downward.org/).
|
||||||
|
|
||||||
Please get in touch with [Patrick Lühne](https://www.luehne.de) if you have any suggestions.
|
Please get in touch with [Patrick Lühne](https://www.luehne.de) if you have any suggestions.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
To translate an SAS file into ASP facts, call:
|
### Translating PDDL to ASP Facts
|
||||||
|
|
||||||
|
PDDL instances are translated to ASP facts as follows:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ plasp file.sas
|
$ plasp domain.pddl problem.pddl
|
||||||
```
|
```
|
||||||
|
|
||||||
For instance, a PDDL instance can be solved as follows.
|
Alternatively, PDDL instances may first be translated to SAS, the output format of [Fast Downward](http://www.fast-downward.org/).
|
||||||
First, use [Fast Downward](http://www.fast-downward.org/) to translate the files from PDDL to SAS:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ ./fast-downward.py --translate --build=release64 domain.pddl instance.pddl
|
$ ./fast-downward.py --translate --build=release64 domain.pddl instance.pddl
|
||||||
```
|
```
|
||||||
|
|
||||||
This creates the file `output.sas`.
|
This creates a file called `output.sas`, which may now be translated by `plasp`.
|
||||||
The translated SAS instance can now be solved incrementally with `clingo` and the meta encoding `meta-sequential-incremental.lp`:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ plasp output.sas > instance.lp
|
$ plasp output.sas
|
||||||
$ clingo encodings/meta-sequential-incremental.lp instance.lp
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Solving the Translated Instance
|
||||||
|
|
||||||
|
The translated instance can finally be solved incrementally with `clingo` and a meta encoding, for instance, `pddl-meta-sequential-incremental.lp`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ plasp domain.pddl problem.pddl > instance.lp
|
||||||
|
$ clingo encodings/pddl-meta-sequential-incremental.lp instance.lp
|
||||||
|
```
|
||||||
|
|
||||||
|
### Command-Line Interface
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ plasp [files] [options]
|
||||||
|
```
|
||||||
|
|
||||||
|
`[files]` may be omitted, in which case the input is read from `std::cin`.
|
||||||
|
The `[options]` are listed below:
|
||||||
|
|
||||||
|
| **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`). |
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
`plasp` requires a C++14 compiler (preferrably GCC ≥ 6.1), the `boost` libraries (≥ 1.55), and CMake for building.
|
`plasp` requires a C++14 compiler (preferrably GCC ≥ 6.1 or clang ≥ 3.8), the `boost` libraries (≥ 1.55), and CMake for building.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ git clone https://github.com/potassco/plasp.git
|
$ git clone https://github.com/potassco/plasp.git
|
||||||
@@ -46,11 +72,27 @@ $ make
|
|||||||
|
|
||||||
The built `plasp` binary is then located at `plasp/build/release/bin/plasp`.
|
The built `plasp` binary is then located at `plasp/build/release/bin/plasp`.
|
||||||
|
|
||||||
|
### 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:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ git submodule init
|
||||||
|
$ git submodule update
|
||||||
|
```
|
||||||
|
|
||||||
|
Afterward, build and run the tests as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ make run-tests
|
||||||
|
```
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
|
|
||||||
* [Patrick Lühne](https://www.luehne.de) (`plasp` 3)
|
* [Patrick Lühne](https://www.luehne.de) (`plasp` 3)
|
||||||
|
|
||||||
### Earlier Versions
|
### Earlier Versions
|
||||||
|
|
||||||
* René Knaebel (`plasp` 2)
|
* René Knaebel
|
||||||
* Murat Knecht (`plasp`)
|
* Murat Knecht
|
||||||
|
@@ -1,9 +1,16 @@
|
|||||||
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
|
|
||||||
|
#include <plasp/LanguageDetection.h>
|
||||||
|
#include <plasp/pddl/Description.h>
|
||||||
|
#include <plasp/pddl/TranslatorASP.h>
|
||||||
#include <plasp/sas/Description.h>
|
#include <plasp/sas/Description.h>
|
||||||
#include <plasp/sas/TranslatorASP.h>
|
#include <plasp/sas/TranslatorASP.h>
|
||||||
|
#include <plasp/utils/LogStream.h>
|
||||||
|
#include <plasp/utils/TranslatorException.h>
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@@ -13,7 +20,10 @@ int main(int argc, char **argv)
|
|||||||
description.add_options()
|
description.add_options()
|
||||||
("help,h", "Display this help message.")
|
("help,h", "Display this help message.")
|
||||||
("version,v", "Display version information.")
|
("version,v", "Display version information.")
|
||||||
("input,i", po::value<std::string>(), "Specify the SAS input file.");
|
("input,i", po::value<std::vector<std::string>>(), "Specify the PDDL or SAS input file.")
|
||||||
|
("language,l", po::value<std::string>(), "Specify the input language (sas or pddl). Omit for automatic detection.")
|
||||||
|
("warning-level", po::value<std::string>()->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<std::string>()->default_value("auto"), "Specify whether to colorize the output (always, never, or auto).");
|
||||||
|
|
||||||
po::positional_options_description positionalOptionsDescription;
|
po::positional_options_description positionalOptionsDescription;
|
||||||
positionalOptionsDescription.add("input", -1);
|
positionalOptionsDescription.add("input", -1);
|
||||||
@@ -23,12 +33,14 @@ int main(int argc, char **argv)
|
|||||||
const auto printHelp =
|
const auto printHelp =
|
||||||
[&]()
|
[&]()
|
||||||
{
|
{
|
||||||
std::cout << "Usage: plasp file [options]" << std::endl;
|
std::cout << "Usage: plasp [files] [options]" << std::endl;
|
||||||
std::cout << "Translate PDDL instances to ASP facts." << std::endl << std::endl;
|
std::cout << "Translate PDDL instances to ASP facts." << std::endl << std::endl;
|
||||||
|
|
||||||
std::cout << description;
|
std::cout << description;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
plasp::utils::Logger logger;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
po::store(po::command_line_parser(argc, argv)
|
po::store(po::command_line_parser(argc, argv)
|
||||||
@@ -40,7 +52,8 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
catch (const po::error &e)
|
catch (const po::error &e)
|
||||||
{
|
{
|
||||||
std::cerr << "Error: " << e.what() << std::endl << std::endl;
|
logger.logError(e.what());
|
||||||
|
std::cout << std::endl;
|
||||||
printHelp();
|
printHelp();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
@@ -53,27 +66,110 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
if (variablesMap.count("version"))
|
if (variablesMap.count("version"))
|
||||||
{
|
{
|
||||||
std::cout << "plasp version 3.0.0" << std::endl;
|
std::cout << "plasp version 3.0.1" << std::endl;
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!variablesMap.count("input"))
|
const auto warningLevel = variablesMap["warning-level"].as<std::string>();
|
||||||
|
|
||||||
|
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);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
std::cerr << "Error: No input file specified" << std::endl << std::endl;
|
logger.logError("unknown warning level “" + warningLevel + "”");
|
||||||
|
std::cout << std::endl;
|
||||||
|
printHelp();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto colorPolicy = variablesMap["color"].as<std::string>();
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
logger.logError("unknown color policy “" + colorPolicy + "”");
|
||||||
|
std::cout << std::endl;
|
||||||
printHelp();
|
printHelp();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const auto sasDescription = plasp::sas::Description::fromFile(variablesMap["input"].as<std::string>());
|
plasp::utils::Parser parser;
|
||||||
const auto sasTranslator = plasp::sas::TranslatorASP(sasDescription);
|
|
||||||
sasTranslator.translate(std::cout);
|
parser.setCaseSensitive(false);
|
||||||
|
|
||||||
|
if (variablesMap.count("input"))
|
||||||
|
{
|
||||||
|
const auto &inputFiles = variablesMap["input"].as<std::vector<std::string>>();
|
||||||
|
|
||||||
|
std::for_each(inputFiles.cbegin(), inputFiles.cend(),
|
||||||
|
[&](const auto &inputFile)
|
||||||
|
{
|
||||||
|
parser.readFile(inputFile);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
parser.readStream("std::cin", std::cin);
|
||||||
|
|
||||||
|
const auto detectLanguage =
|
||||||
|
[&]()
|
||||||
|
{
|
||||||
|
if (variablesMap.count("language") == 0)
|
||||||
|
return plasp::detectLanguage(parser);
|
||||||
|
|
||||||
|
const auto languageName = variablesMap["language"].as<std::string>();
|
||||||
|
|
||||||
|
return plasp::Language::fromString(languageName);
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto language = detectLanguage();
|
||||||
|
|
||||||
|
if (language == plasp::Language::Type::Unknown)
|
||||||
|
{
|
||||||
|
logger.logError("unknown input language");
|
||||||
|
std::cout << std::endl;
|
||||||
|
printHelp();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
translator.translate();
|
||||||
|
}
|
||||||
|
else if (language == plasp::Language::Type::SAS)
|
||||||
|
{
|
||||||
|
const auto description = plasp::sas::Description::fromParser(std::move(parser));
|
||||||
|
const auto translator = plasp::sas::TranslatorASP(description, logger.outputStream());
|
||||||
|
translator.translate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const plasp::utils::ParserException &e)
|
||||||
|
{
|
||||||
|
logger.logError(e.coordinate(), e.message());
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
catch (const plasp::utils::TranslatorException &e)
|
||||||
|
{
|
||||||
|
logger.logError(e.what());
|
||||||
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception &e)
|
||||||
{
|
{
|
||||||
std::cerr << "Error: " << e.what() << std::endl << std::endl;
|
logger.logError(e.what());
|
||||||
printHelp();
|
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
31
encodings/pddl-meta-sequential-incremental.lp
Normal file
31
encodings/pddl-meta-sequential-incremental.lp
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#include <incmode>.
|
||||||
|
|
||||||
|
#program base.
|
||||||
|
|
||||||
|
% Establish initial state
|
||||||
|
holds(Predicate, 0) :- initialState(Predicate).
|
||||||
|
|
||||||
|
#program step(t).
|
||||||
|
|
||||||
|
% Perform actions
|
||||||
|
1 {occurs(action(Action), t) : action(Action)} 1.
|
||||||
|
|
||||||
|
% Check preconditions
|
||||||
|
:- occurs(Action, t), precondition(Action, Predicate, true), not holds(Predicate, t - 1).
|
||||||
|
:- occurs(Action, t), precondition(Action, Predicate, false), holds(Predicate, t - 1).
|
||||||
|
|
||||||
|
% Apply effects
|
||||||
|
caused(Predicate, true, t) :- occurs(Action, t), postcondition(Action, Predicate, true).
|
||||||
|
caused(Predicate, false, t) :- occurs(Action, t), postcondition(Action, Predicate, false).
|
||||||
|
|
||||||
|
holds(Predicate, t) :- caused(Predicate, true, t).
|
||||||
|
holds(Predicate, t) :- holds(Predicate, t - 1), not caused(Predicate, false, t).
|
||||||
|
|
||||||
|
#program check(t).
|
||||||
|
|
||||||
|
% Verify that goal is met
|
||||||
|
:- query(t), goal(Predicate, true), not holds(Predicate, t).
|
||||||
|
:- query(t), goal(Predicate, false), holds(Predicate, t).
|
||||||
|
|
||||||
|
#show query/1.
|
||||||
|
#show occurs/2.
|
36
include/plasp/Language.h
Normal file
36
include/plasp/Language.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef __PLASP__LANGUAGE_H
|
||||||
|
#define __PLASP__LANGUAGE_H
|
||||||
|
|
||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Language
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Language
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class Type
|
||||||
|
{
|
||||||
|
Unknown,
|
||||||
|
PDDL,
|
||||||
|
SAS
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::string toString(Type language);
|
||||||
|
static Language::Type fromString(const std::string &languageName);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Language() = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
50
include/plasp/LanguageDetection.h
Normal file
50
include/plasp/LanguageDetection.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#ifndef __PLASP__LANGUAGE_DETECTION_H
|
||||||
|
#define __PLASP__LANGUAGE_DETECTION_H
|
||||||
|
|
||||||
|
#include <plasp/Language.h>
|
||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// LanguageDetection
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Language::Type detectLanguage(utils::Parser &parser)
|
||||||
|
{
|
||||||
|
parser.setCaseSensitive(false);
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
// SAS begins with "begin_version"
|
||||||
|
if (parser.probe<std::string>("begin"))
|
||||||
|
{
|
||||||
|
parser.seek(std::ios::beg);
|
||||||
|
return Language::Type::SAS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip potential PDDL comments
|
||||||
|
while (parser.currentCharacter() == ';')
|
||||||
|
{
|
||||||
|
parser.skipLine();
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// PDDL contains sections starting with "(define"
|
||||||
|
if (parser.probe<std::string>("(") && parser.probe<std::string>("define"))
|
||||||
|
{
|
||||||
|
parser.seek(std::ios::beg);
|
||||||
|
return Language::Type::PDDL;
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.seek(std::ios::beg);
|
||||||
|
return Language::Type::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
48
include/plasp/pddl/Action.h
Normal file
48
include/plasp/pddl/Action.h
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
#ifndef __PLASP__PDDL__ACTION_H
|
||||||
|
#define __PLASP__PDDL__ACTION_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Expression.h>
|
||||||
|
#include <plasp/pddl/expressions/Variable.h>
|
||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Action
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void parseDeclaration(Context &context, Domain &domain);
|
||||||
|
|
||||||
|
public:
|
||||||
|
const std::string &name() const;
|
||||||
|
|
||||||
|
const expressions::Variables ¶meters() const;
|
||||||
|
const Expression *precondition() const;
|
||||||
|
const Expression *effect() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Action() = default;
|
||||||
|
|
||||||
|
std::string m_name;
|
||||||
|
|
||||||
|
expressions::Variables m_parameters;
|
||||||
|
std::unique_ptr<Expression> m_precondition;
|
||||||
|
std::unique_ptr<Expression> m_effect;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
57
include/plasp/pddl/ConsistencyException.h
Normal file
57
include/plasp/pddl/ConsistencyException.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#ifndef __PLASP__PDDL__CONSISTENCY_EXCEPTION_H
|
||||||
|
#define __PLASP__PDDL__CONSISTENCY_EXCEPTION_H
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// ConsistencyException
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class ConsistencyException: public std::exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ConsistencyException()
|
||||||
|
: ConsistencyException("unspecified consistency error")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit ConsistencyException(const char *message)
|
||||||
|
: ConsistencyException(static_cast<std::string>(message))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit ConsistencyException(const std::string &message)
|
||||||
|
: m_message{message}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~ConsistencyException() throw()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *what() const throw()
|
||||||
|
{
|
||||||
|
if (m_message.empty())
|
||||||
|
return "unspecified consistency error";
|
||||||
|
|
||||||
|
return m_message.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_message;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
68
include/plasp/pddl/Context.h
Normal file
68
include/plasp/pddl/Context.h
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#ifndef __PLASP__PDDL__CONTEXT_H
|
||||||
|
#define __PLASP__PDDL__CONTEXT_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <plasp/utils/Logger.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Context
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Context() = default;
|
||||||
|
|
||||||
|
explicit Context(utils::Parser &&parser)
|
||||||
|
: parser{std::move(parser)}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit Context(utils::Logger &&logger)
|
||||||
|
: logger{std::move(logger)}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit Context(utils::Parser &&parser, utils::Logger &&logger)
|
||||||
|
: parser{std::move(parser)},
|
||||||
|
logger{std::move(logger)}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Context(const Context &other) = delete;
|
||||||
|
Context &operator=(const Context &other) = delete;
|
||||||
|
|
||||||
|
Context(Context &&other)
|
||||||
|
: parser(std::move(other.parser)),
|
||||||
|
logger(std::move(other.logger))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Context &operator=(Context &&other)
|
||||||
|
{
|
||||||
|
parser = std::move(other.parser);
|
||||||
|
logger = std::move(other.logger);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
utils::Parser parser;
|
||||||
|
utils::Logger logger;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
59
include/plasp/pddl/Description.h
Normal file
59
include/plasp/pddl/Description.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#ifndef __PLASP__PDDL__DESCRIPTION_H
|
||||||
|
#define __PLASP__PDDL__DESCRIPTION_H
|
||||||
|
|
||||||
|
#include <boost/filesystem/path.hpp>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Domain.h>
|
||||||
|
#include <plasp/pddl/Problem.h>
|
||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Description
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
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<std::string> &paths);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Context &context();
|
||||||
|
const Context &context() const;
|
||||||
|
|
||||||
|
const Domain &domain() const;
|
||||||
|
|
||||||
|
bool containsProblem() const;
|
||||||
|
const Problem &problem() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Description();
|
||||||
|
|
||||||
|
void parse();
|
||||||
|
void findSections();
|
||||||
|
|
||||||
|
void checkConsistency();
|
||||||
|
|
||||||
|
Context m_context;
|
||||||
|
|
||||||
|
utils::Parser::Position m_domainPosition;
|
||||||
|
std::unique_ptr<Domain> m_domain;
|
||||||
|
utils::Parser::Position m_problemPosition;
|
||||||
|
std::unique_ptr<Problem> m_problem;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
92
include/plasp/pddl/Domain.h
Normal file
92
include/plasp/pddl/Domain.h
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
#ifndef __PLASP__PDDL__DOMAIN_H
|
||||||
|
#define __PLASP__PDDL__DOMAIN_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/Action.h>
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/Expression.h>
|
||||||
|
#include <plasp/pddl/expressions/Constant.h>
|
||||||
|
#include <plasp/pddl/expressions/PredicateDeclaration.h>
|
||||||
|
#include <plasp/pddl/expressions/PrimitiveType.h>
|
||||||
|
#include <plasp/pddl/Requirement.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Domain
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Domain
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Domain(Context &context);
|
||||||
|
|
||||||
|
public:
|
||||||
|
void findSections();
|
||||||
|
void parse();
|
||||||
|
|
||||||
|
void setName(std::string name);
|
||||||
|
const std::string &name() const;
|
||||||
|
|
||||||
|
const Requirements &requirements() const;
|
||||||
|
bool hasRequirement(Requirement::Type requirementType) const;
|
||||||
|
void checkRequirement(Requirement::Type requirementType) const;
|
||||||
|
|
||||||
|
expressions::PrimitiveTypes &types();
|
||||||
|
const expressions::PrimitiveTypes &types() const;
|
||||||
|
|
||||||
|
expressions::Constants &constants();
|
||||||
|
const expressions::Constants &constants() const;
|
||||||
|
|
||||||
|
expressions::PredicateDeclarations &predicates();
|
||||||
|
const expressions::PredicateDeclarations &predicates() const;
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<Action>> &actions();
|
||||||
|
const std::vector<std::unique_ptr<Action>> &actions() const;
|
||||||
|
|
||||||
|
void checkConsistency();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void parseSection();
|
||||||
|
|
||||||
|
void parseRequirementSection();
|
||||||
|
void computeDerivedRequirements();
|
||||||
|
|
||||||
|
void parseTypeSection();
|
||||||
|
|
||||||
|
void parseConstantSection();
|
||||||
|
|
||||||
|
void parsePredicateSection();
|
||||||
|
|
||||||
|
void parseActionSection();
|
||||||
|
|
||||||
|
Context &m_context;
|
||||||
|
|
||||||
|
std::string m_name;
|
||||||
|
|
||||||
|
utils::Parser::Position m_requirementsPosition;
|
||||||
|
Requirements m_requirements;
|
||||||
|
|
||||||
|
utils::Parser::Position m_typesPosition;
|
||||||
|
expressions::PrimitiveTypes m_types;
|
||||||
|
|
||||||
|
utils::Parser::Position m_constantsPosition;
|
||||||
|
expressions::Constants m_constants;
|
||||||
|
|
||||||
|
utils::Parser::Position m_predicatesPosition;
|
||||||
|
expressions::PredicateDeclarations m_predicates;
|
||||||
|
|
||||||
|
std::vector<utils::Parser::Position> m_actionPositions;
|
||||||
|
std::vector<std::unique_ptr<Action>> m_actions;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
130
include/plasp/pddl/Expression.h
Normal file
130
include/plasp/pddl/Expression.h
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
#ifndef __PLASP__PDDL__EXPRESSION_H
|
||||||
|
#define __PLASP__PDDL__EXPRESSION_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Expression
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Context;
|
||||||
|
class Domain;
|
||||||
|
class ExpressionContext;
|
||||||
|
class ExpressionVisitor;
|
||||||
|
class Problem;
|
||||||
|
|
||||||
|
class Expression;
|
||||||
|
using ExpressionPointer = std::unique_ptr<Expression>;
|
||||||
|
using Expressions = std::vector<ExpressionPointer>;
|
||||||
|
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
class And;
|
||||||
|
using AndPointer = std::unique_ptr<And>;
|
||||||
|
|
||||||
|
class At;
|
||||||
|
using AtPointer = std::unique_ptr<At>;
|
||||||
|
|
||||||
|
class Constant;
|
||||||
|
using ConstantPointer = std::unique_ptr<Constant>;
|
||||||
|
using Constants = std::vector<ConstantPointer>;
|
||||||
|
|
||||||
|
class Either;
|
||||||
|
using EitherPointer = std::unique_ptr<Either>;
|
||||||
|
|
||||||
|
class Imply;
|
||||||
|
using ImplyPointer = std::unique_ptr<Imply>;
|
||||||
|
|
||||||
|
class Not;
|
||||||
|
using NotPointer = std::unique_ptr<Not>;
|
||||||
|
|
||||||
|
class Or;
|
||||||
|
using OrPointer = std::unique_ptr<Or>;
|
||||||
|
|
||||||
|
class Predicate;
|
||||||
|
using PredicatePointer = std::unique_ptr<Predicate>;
|
||||||
|
using Predicates = std::vector<PredicatePointer>;
|
||||||
|
|
||||||
|
class PredicateDeclaration;
|
||||||
|
using PredicateDeclarationPointer = std::unique_ptr<PredicateDeclaration>;
|
||||||
|
using PredicateDeclarations = std::vector<PredicateDeclarationPointer>;
|
||||||
|
|
||||||
|
class PrimitiveType;
|
||||||
|
using PrimitiveTypePointer = std::unique_ptr<PrimitiveType>;
|
||||||
|
using PrimitiveTypes = std::vector<PrimitiveTypePointer>;
|
||||||
|
|
||||||
|
class Unsupported;
|
||||||
|
using UnsupportedPointer = std::unique_ptr<Unsupported>;
|
||||||
|
|
||||||
|
class Variable;
|
||||||
|
using VariablePointer = std::unique_ptr<Variable>;
|
||||||
|
using Variables = std::vector<VariablePointer>;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Expression
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class Type
|
||||||
|
{
|
||||||
|
And,
|
||||||
|
At,
|
||||||
|
Binary,
|
||||||
|
Constant,
|
||||||
|
Either,
|
||||||
|
Imply,
|
||||||
|
Not,
|
||||||
|
Or,
|
||||||
|
PredicateDeclaration,
|
||||||
|
Predicate,
|
||||||
|
PrimitiveType,
|
||||||
|
Unsupported,
|
||||||
|
Variable
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~Expression() = default;
|
||||||
|
|
||||||
|
virtual Type expressionType() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Derived>
|
||||||
|
class ExpressionCRTP: public Expression
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Type expressionType() const override final
|
||||||
|
{
|
||||||
|
return Derived::ExpressionType;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ExpressionPointer parseLiteral(Context &context, ExpressionContext &expressionContext);
|
||||||
|
ExpressionPointer parseAtomicFormula(Context &context, ExpressionContext &expressionContext);
|
||||||
|
|
||||||
|
ExpressionPointer parsePreconditionExpression(Context &context,
|
||||||
|
ExpressionContext &expressionContext);
|
||||||
|
ExpressionPointer parseExpression(Context &context, ExpressionContext &expressionContext);
|
||||||
|
|
||||||
|
ExpressionPointer parseEffectExpression(Context &context,
|
||||||
|
ExpressionContext &expressionContext);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
38
include/plasp/pddl/ExpressionContext.h
Normal file
38
include/plasp/pddl/ExpressionContext.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#ifndef __PLASP__PDDL__EXPRESSION_CONTEXT_H
|
||||||
|
#define __PLASP__PDDL__EXPRESSION_CONTEXT_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/Expression.h>
|
||||||
|
#include <plasp/pddl/Requirement.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// ExpressionContext
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class ExpressionContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ExpressionContext(Domain &domain, expressions::Variables ¶meters);
|
||||||
|
ExpressionContext(Domain &domain, Problem *problem, expressions::Variables ¶meters);
|
||||||
|
|
||||||
|
bool hasRequirement(Requirement::Type requirementType) const;
|
||||||
|
void checkRequirement(Requirement::Type requirementType) const;
|
||||||
|
|
||||||
|
Domain &domain;
|
||||||
|
Problem *problem;
|
||||||
|
|
||||||
|
expressions::Variables ¶meters;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
45
include/plasp/pddl/IO.h
Normal file
45
include/plasp/pddl/IO.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#ifndef __PLASP__PDDL__IO_H
|
||||||
|
#define __PLASP__PDDL__IO_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// IO
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
inline void skipSection(utils::Parser &parser)
|
||||||
|
{
|
||||||
|
size_t openParentheses = 1;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
const auto character = parser.currentCharacter();
|
||||||
|
parser.advance();
|
||||||
|
|
||||||
|
if (character == '(')
|
||||||
|
openParentheses++;
|
||||||
|
else if (character == ')')
|
||||||
|
{
|
||||||
|
openParentheses--;
|
||||||
|
|
||||||
|
if (openParentheses == 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
32
include/plasp/pddl/Identifier.h
Normal file
32
include/plasp/pddl/Identifier.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#ifndef __PLASP__PDDL__IDENTIFIER_H
|
||||||
|
#define __PLASP__PDDL__IDENTIFIER_H
|
||||||
|
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Identifier
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const auto isIdentifier =
|
||||||
|
[](const auto character)
|
||||||
|
{
|
||||||
|
return character != '?'
|
||||||
|
&& character != '('
|
||||||
|
&& character != ')'
|
||||||
|
&& character != ';'
|
||||||
|
&& std::isgraph(character);
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
35
include/plasp/pddl/InitialState.h
Normal file
35
include/plasp/pddl/InitialState.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#ifndef __PLASP__PDDL__EXPRESSIONS__INITIAL_STATE_H
|
||||||
|
#define __PLASP__PDDL__EXPRESSIONS__INITIAL_STATE_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/Expression.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// InitialState
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class InitialState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::unique_ptr<InitialState> parseDeclaration(Context &context,
|
||||||
|
ExpressionContext &expressionContext);
|
||||||
|
|
||||||
|
public:
|
||||||
|
const Expressions &facts() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Expressions m_facts;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
84
include/plasp/pddl/Problem.h
Normal file
84
include/plasp/pddl/Problem.h
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
#ifndef __PLASP__PDDL__PROBLEM_H
|
||||||
|
#define __PLASP__PDDL__PROBLEM_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/Expression.h>
|
||||||
|
#include <plasp/pddl/InitialState.h>
|
||||||
|
#include <plasp/pddl/Requirement.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Problem
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Problem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Problem(Context &context, Domain &domain);
|
||||||
|
|
||||||
|
void findSections();
|
||||||
|
void parse();
|
||||||
|
|
||||||
|
Domain &domain();
|
||||||
|
const Domain &domain() const;
|
||||||
|
|
||||||
|
const std::string &name() const;
|
||||||
|
|
||||||
|
const Requirements &requirements() const;
|
||||||
|
bool hasRequirement(Requirement::Type requirementType) const;
|
||||||
|
void checkRequirement(Requirement::Type requirementType) const;
|
||||||
|
|
||||||
|
expressions::Constants &objects();
|
||||||
|
const expressions::Constants &objects() const;
|
||||||
|
|
||||||
|
InitialState &initialState();
|
||||||
|
const InitialState &initialState() const;
|
||||||
|
|
||||||
|
const Expression &goal() const;
|
||||||
|
|
||||||
|
void checkConsistency();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void parseRequirementSection();
|
||||||
|
void computeDerivedRequirements();
|
||||||
|
|
||||||
|
void parseDomainSection();
|
||||||
|
|
||||||
|
void parseObjectSection();
|
||||||
|
|
||||||
|
void parseInitialStateSection();
|
||||||
|
|
||||||
|
void parseGoalSection();
|
||||||
|
|
||||||
|
Context &m_context;
|
||||||
|
Domain &m_domain;
|
||||||
|
|
||||||
|
std::string m_name;
|
||||||
|
|
||||||
|
utils::Parser::Position m_domainPosition;
|
||||||
|
|
||||||
|
utils::Parser::Position m_requirementsPosition;
|
||||||
|
Requirements m_requirements;
|
||||||
|
|
||||||
|
utils::Parser::Position m_objectsPosition;
|
||||||
|
expressions::Constants m_objects;
|
||||||
|
|
||||||
|
utils::Parser::Position m_initialStatePosition;
|
||||||
|
std::unique_ptr<InitialState> m_initialState;
|
||||||
|
|
||||||
|
utils::Parser::Position m_goalPosition;
|
||||||
|
ExpressionPointer m_goal;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
72
include/plasp/pddl/Requirement.h
Normal file
72
include/plasp/pddl/Requirement.h
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#ifndef __PLASP__PDDL__REQUIREMENT_H
|
||||||
|
#define __PLASP__PDDL__REQUIREMENT_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Requirement
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Requirement;
|
||||||
|
using Requirements = std::vector<Requirement>;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Requirement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class Type
|
||||||
|
{
|
||||||
|
STRIPS,
|
||||||
|
Typing,
|
||||||
|
NegativePreconditions,
|
||||||
|
DisjunctivePreconditions,
|
||||||
|
Equality,
|
||||||
|
ExistentialPreconditions,
|
||||||
|
UniversalPreconditions,
|
||||||
|
QuantifiedPreconditions,
|
||||||
|
ConditionalEffects,
|
||||||
|
Fluents,
|
||||||
|
NumericFluents,
|
||||||
|
ObjectFluents,
|
||||||
|
ADL,
|
||||||
|
DurativeActions,
|
||||||
|
DurationInequalities,
|
||||||
|
ContinuousEffects,
|
||||||
|
DerivedPredicates,
|
||||||
|
TimedInitialLiterals,
|
||||||
|
Preferences,
|
||||||
|
Constraints,
|
||||||
|
ActionCosts,
|
||||||
|
GoalUtilities
|
||||||
|
};
|
||||||
|
|
||||||
|
static Requirement parse(Context &context);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Requirement(Type type);
|
||||||
|
|
||||||
|
Type type() const;
|
||||||
|
|
||||||
|
std::string toPDDL() const;
|
||||||
|
std::string toASP() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Type m_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
51
include/plasp/pddl/TranslatorASP.h
Normal file
51
include/plasp/pddl/TranslatorASP.h
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#ifndef __PLASP__PDDL__TRANSLATOR_ASP_H
|
||||||
|
#define __PLASP__PDDL__TRANSLATOR_ASP_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/Description.h>
|
||||||
|
|
||||||
|
#include <iosfwd>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// TranslatorASP
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class TranslatorASP
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit TranslatorASP(const Description &description, utils::LogStream &outputStream);
|
||||||
|
|
||||||
|
void translate() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void translateDomain() const;
|
||||||
|
void translateTypes() const;
|
||||||
|
void translatePredicates() const;
|
||||||
|
void translateActions() const;
|
||||||
|
|
||||||
|
void translateProblem() const;
|
||||||
|
void translateInitialState() const;
|
||||||
|
void translateGoal() const;
|
||||||
|
|
||||||
|
void translateConstants(const std::string &heading, const expressions::Constants &constants) const;
|
||||||
|
void translateVariablesHead(const expressions::Variables &variables) const;
|
||||||
|
void translateVariablesBody(const expressions::Variables &variables) const;
|
||||||
|
void translateLiteral(const Expression &literal) const;
|
||||||
|
void translatePredicate(const expressions::Predicate &predicate) const;
|
||||||
|
|
||||||
|
const Description &m_description;
|
||||||
|
utils::LogStream &m_outputStream;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
33
include/plasp/pddl/expressions/And.h
Normal file
33
include/plasp/pddl/expressions/And.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#ifndef __PLASP__PDDL__EXPRESSIONS__AND_H
|
||||||
|
#define __PLASP__PDDL__EXPRESSIONS__AND_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/expressions/NAry.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// And
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class And: public NAry<And>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const Expression::Type ExpressionType = Expression::Type::And;
|
||||||
|
|
||||||
|
static const std::string Identifier;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
106
include/plasp/pddl/expressions/At.h
Normal file
106
include/plasp/pddl/expressions/At.h
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
#ifndef __PLASP__PDDL__EXPRESSIONS__AT_H
|
||||||
|
#define __PLASP__PDDL__EXPRESSIONS__AT_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/Expression.h>
|
||||||
|
#include <plasp/pddl/Identifier.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// At
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class At: public ExpressionCRTP<At>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const Expression::Type ExpressionType = Expression::Type::At;
|
||||||
|
|
||||||
|
template<typename ExpressionParser>
|
||||||
|
static AtPointer parse(Context &context, ExpressionContext &expressionContext,
|
||||||
|
ExpressionParser parseExpression);
|
||||||
|
|
||||||
|
static const size_t TimePointStart = std::numeric_limits<size_t>::max();
|
||||||
|
static const size_t TimePointEnd = std::numeric_limits<size_t>::max() - 1;
|
||||||
|
|
||||||
|
public:
|
||||||
|
At();
|
||||||
|
|
||||||
|
size_t timePoint() const;
|
||||||
|
|
||||||
|
const Expression *argument() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setArgument(const Expression *argument);
|
||||||
|
void setArgument(ExpressionPointer &&argument);
|
||||||
|
|
||||||
|
size_t m_timePoint;
|
||||||
|
|
||||||
|
const Expression *m_argument;
|
||||||
|
ExpressionPointer m_argumentStorage;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<typename ExpressionParser>
|
||||||
|
AtPointer At::parse(Context &context, ExpressionContext &expressionContext,
|
||||||
|
ExpressionParser parseExpression)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
if (!parser.probe<std::string>("(")
|
||||||
|
|| !parser.probeIdentifier("at", isIdentifier))
|
||||||
|
{
|
||||||
|
parser.seek(position);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t timePoint;
|
||||||
|
|
||||||
|
const auto timePointPosition = parser.position();
|
||||||
|
|
||||||
|
if (parser.probeIdentifier("start", isIdentifier))
|
||||||
|
timePoint = TimePointStart;
|
||||||
|
else if (parser.probeIdentifier("end", isIdentifier))
|
||||||
|
timePoint = TimePointEnd;
|
||||||
|
else if (parser.probeNumber())
|
||||||
|
{
|
||||||
|
parser.seek(timePointPosition);
|
||||||
|
timePoint = parser.parse<size_t>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parser.seek(position);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto expression = std::make_unique<At>(At());
|
||||||
|
|
||||||
|
expression->m_timePoint = timePoint;
|
||||||
|
|
||||||
|
context.parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
// Parse argument
|
||||||
|
expression->setArgument(parseExpression(context, expressionContext));
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
112
include/plasp/pddl/expressions/Binary.h
Normal file
112
include/plasp/pddl/expressions/Binary.h
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
#ifndef __PLASP__PDDL__EXPRESSIONS__BINARY_H
|
||||||
|
#define __PLASP__PDDL__EXPRESSIONS__BINARY_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/ConsistencyException.h>
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/Expression.h>
|
||||||
|
#include <plasp/pddl/Identifier.h>
|
||||||
|
#include <plasp/pddl/expressions/Variable.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Binary
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Derived>
|
||||||
|
class Binary: public ExpressionCRTP<Derived>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template<typename ExpressionParser>
|
||||||
|
static std::unique_ptr<Derived> parse(Context &context,
|
||||||
|
ExpressionContext &expressionContext, ExpressionParser parseExpression);
|
||||||
|
|
||||||
|
public:
|
||||||
|
const std::array<const Expression *, 2> &arguments() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<size_t i>
|
||||||
|
void setArgument(const Expression *argument);
|
||||||
|
template<size_t i>
|
||||||
|
void setArgument(ExpressionPointer &&argument);
|
||||||
|
|
||||||
|
std::array<const Expression *, 2> m_arguments;
|
||||||
|
std::array<ExpressionPointer, 2> m_argumentStorage;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Derived>
|
||||||
|
template<typename ExpressionParser>
|
||||||
|
std::unique_ptr<Derived> Binary<Derived>::parse(Context &context,
|
||||||
|
ExpressionContext &expressionContext, ExpressionParser parseExpression)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
if (!parser.probe<std::string>("(")
|
||||||
|
|| !parser.probeIdentifier(Derived::Identifier, isIdentifier))
|
||||||
|
{
|
||||||
|
parser.seek(position);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto expression = std::make_unique<Derived>();
|
||||||
|
|
||||||
|
// Assume that expression identifier (imply, exists, etc.) is already parsed
|
||||||
|
// Parse arguments of the expression
|
||||||
|
expression->Binary<Derived>::setArgument<0>(parseExpression(context, expressionContext));
|
||||||
|
expression->Binary<Derived>::setArgument<1>(parseExpression(context, expressionContext));
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Derived>
|
||||||
|
template<size_t i>
|
||||||
|
void Binary<Derived>::setArgument(const Expression *expression)
|
||||||
|
{
|
||||||
|
static_assert(i <= 2, "Index out of range");
|
||||||
|
|
||||||
|
m_argumentStorage[i] = nullptr;
|
||||||
|
m_arguments[i] = expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Derived>
|
||||||
|
template<size_t i>
|
||||||
|
void Binary<Derived>::setArgument(ExpressionPointer &&expression)
|
||||||
|
{
|
||||||
|
static_assert(i <= 2, "Index out of range");
|
||||||
|
|
||||||
|
m_argumentStorage[i] = std::move(expression);
|
||||||
|
m_arguments[i] = m_argumentStorage[i].get();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Derived>
|
||||||
|
const std::array<const Expression *, 2> &Binary<Derived>::arguments() const
|
||||||
|
{
|
||||||
|
return m_arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
65
include/plasp/pddl/expressions/Constant.h
Normal file
65
include/plasp/pddl/expressions/Constant.h
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
#ifndef __PLASP__PDDL__EXPRESSIONS__CONSTANT_H
|
||||||
|
#define __PLASP__PDDL__EXPRESSIONS__CONSTANT_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/Expression.h>
|
||||||
|
#include <plasp/pddl/Identifier.h>
|
||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
#include <plasp/utils/ParserException.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Constant
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Constant: public ExpressionCRTP<Constant>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const Expression::Type ExpressionType = Expression::Type::Constant;
|
||||||
|
|
||||||
|
static void parseTypedDeclaration(Context &context, Domain &domain);
|
||||||
|
static void parseTypedDeclarations(Context &context, Domain &domain);
|
||||||
|
static void parseTypedDeclaration(Context &context, Problem &problem);
|
||||||
|
static void parseTypedDeclarations(Context &context, Problem &problem);
|
||||||
|
|
||||||
|
static Constant *parseAndFind(Context &context, const Domain &domain);
|
||||||
|
static Constant *parseAndFind(Context &context, const Problem &problem);
|
||||||
|
|
||||||
|
public:
|
||||||
|
const std::string &name() const;
|
||||||
|
const PrimitiveType *type() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static ConstantPointer parseDeclaration(Context &context);
|
||||||
|
static void parseTypedDeclaration(Context &context, Domain &domain, Constants &constants);
|
||||||
|
|
||||||
|
static Constant *parseAndFind(const std::string &constantName, const Constants &constants);
|
||||||
|
|
||||||
|
Constant();
|
||||||
|
|
||||||
|
void setDirty(bool isDirty = true);
|
||||||
|
bool isDirty() const;
|
||||||
|
|
||||||
|
void setType(const PrimitiveType *parentType);
|
||||||
|
|
||||||
|
bool m_isDirty;
|
||||||
|
|
||||||
|
std::string m_name;
|
||||||
|
|
||||||
|
const PrimitiveType *m_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
33
include/plasp/pddl/expressions/Either.h
Normal file
33
include/plasp/pddl/expressions/Either.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#ifndef __PLASP__PDDL__EXPRESSIONS__EITHER_H
|
||||||
|
#define __PLASP__PDDL__EXPRESSIONS__EITHER_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/expressions/NAry.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Either
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Either: public NAry<Either>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const Expression::Type ExpressionType = Expression::Type::Either;
|
||||||
|
|
||||||
|
static const std::string Identifier;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
33
include/plasp/pddl/expressions/Imply.h
Normal file
33
include/plasp/pddl/expressions/Imply.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#ifndef __PLASP__PDDL__EXPRESSIONS__IMPLY_H
|
||||||
|
#define __PLASP__PDDL__EXPRESSIONS__IMPLY_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/expressions/Binary.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Imply
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Imply: public Binary<Imply>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const Expression::Type ExpressionType = Expression::Type::Imply;
|
||||||
|
|
||||||
|
static const std::string Identifier;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
118
include/plasp/pddl/expressions/NAry.h
Normal file
118
include/plasp/pddl/expressions/NAry.h
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
#ifndef __PLASP__PDDL__EXPRESSIONS__N_ARY_H
|
||||||
|
#define __PLASP__PDDL__EXPRESSIONS__N_ARY_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/ConsistencyException.h>
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/Expression.h>
|
||||||
|
#include <plasp/pddl/Identifier.h>
|
||||||
|
#include <plasp/pddl/expressions/Variable.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// NAry
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Derived>
|
||||||
|
class NAry: public ExpressionCRTP<Derived>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template<typename ExpressionParser>
|
||||||
|
static std::unique_ptr<Derived> parse(Context &context,
|
||||||
|
ExpressionContext &expressionContext, ExpressionParser parseExpression);
|
||||||
|
|
||||||
|
public:
|
||||||
|
const std::vector<const Expression *> &arguments() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void addArgument(const Expression *argument);
|
||||||
|
void addArgument(ExpressionPointer &&argument);
|
||||||
|
|
||||||
|
std::vector<const Expression *> m_arguments;
|
||||||
|
Expressions m_argumentStorage;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Derived>
|
||||||
|
template<typename ExpressionParser>
|
||||||
|
std::unique_ptr<Derived> NAry<Derived>::parse(Context &context,
|
||||||
|
ExpressionContext &expressionContext, ExpressionParser parseExpression)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
if (!parser.probe<std::string>("(")
|
||||||
|
|| !parser.probeIdentifier(Derived::Identifier, isIdentifier))
|
||||||
|
{
|
||||||
|
parser.seek(position);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto expression = std::make_unique<Derived>();
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
// Assume that expression identifier (and, or, etc.) is already parsed
|
||||||
|
// Parse arguments of the expression
|
||||||
|
while (parser.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
expression->addArgument(parseExpression(context, expressionContext));
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expression->m_arguments.empty())
|
||||||
|
context.logger.logWarning(context.parser, "“" + Derived::Identifier + "” expressions should not be empty");
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Derived>
|
||||||
|
void NAry<Derived>::addArgument(const Expression *argument)
|
||||||
|
{
|
||||||
|
if (!argument)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_arguments.emplace_back(argument);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Derived>
|
||||||
|
void NAry<Derived>::addArgument(ExpressionPointer &&argument)
|
||||||
|
{
|
||||||
|
if (!argument)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_argumentStorage.emplace_back(std::move(argument));
|
||||||
|
m_arguments.emplace_back(m_argumentStorage.back().get());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Derived>
|
||||||
|
const std::vector<const Expression *> &NAry<Derived>::arguments() const
|
||||||
|
{
|
||||||
|
return m_arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
78
include/plasp/pddl/expressions/Not.h
Normal file
78
include/plasp/pddl/expressions/Not.h
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
#ifndef __PLASP__PDDL__EXPRESSIONS__NOT_H
|
||||||
|
#define __PLASP__PDDL__EXPRESSIONS__NOT_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/Expression.h>
|
||||||
|
#include <plasp/pddl/Identifier.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Not
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Not: public ExpressionCRTP<Not>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const Expression::Type ExpressionType = Expression::Type::Not;
|
||||||
|
|
||||||
|
template<typename ExpressionParser>
|
||||||
|
static NotPointer parse(Context &context, ExpressionContext &expressionContext,
|
||||||
|
ExpressionParser parseExpression);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Not();
|
||||||
|
|
||||||
|
const Expression *argument() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setArgument(const Expression *argument);
|
||||||
|
void setArgument(ExpressionPointer &&argument);
|
||||||
|
|
||||||
|
const Expression *m_argument;
|
||||||
|
ExpressionPointer m_argumentStorage;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<typename ExpressionParser>
|
||||||
|
NotPointer Not::parse(Context &context, ExpressionContext &expressionContext,
|
||||||
|
ExpressionParser parseExpression)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
if (!parser.probe<std::string>("(")
|
||||||
|
|| !parser.probeIdentifier("not", isIdentifier))
|
||||||
|
{
|
||||||
|
parser.seek(position);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto expression = std::make_unique<Not>(Not());
|
||||||
|
|
||||||
|
context.parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
// Parse argument
|
||||||
|
expression->setArgument(parseExpression(context, expressionContext));
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
33
include/plasp/pddl/expressions/Or.h
Normal file
33
include/plasp/pddl/expressions/Or.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#ifndef __PLASP__PDDL__EXPRESSIONS__OR_H
|
||||||
|
#define __PLASP__PDDL__EXPRESSIONS__OR_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/expressions/NAry.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Or
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Or: public NAry<Or>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const Expression::Type ExpressionType = Expression::Type::Or;
|
||||||
|
|
||||||
|
static const std::string Identifier;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
50
include/plasp/pddl/expressions/Predicate.h
Normal file
50
include/plasp/pddl/expressions/Predicate.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#ifndef __PLASP__PDDL__EXPRESSIONS__PREDICATE_H
|
||||||
|
#define __PLASP__PDDL__EXPRESSIONS__PREDICATE_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/Expression.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Predicate
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Predicate: public ExpressionCRTP<Predicate>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const Expression::Type ExpressionType = Expression::Type::Predicate;
|
||||||
|
|
||||||
|
static PredicatePointer parse(Context &context, ExpressionContext &expressionContext);
|
||||||
|
static PredicatePointer parse(Context &context, const Problem &problem);
|
||||||
|
|
||||||
|
public:
|
||||||
|
const std::string &name() const;
|
||||||
|
const std::vector<const Expression *> &arguments() const;
|
||||||
|
|
||||||
|
bool isDeclared() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Predicate();
|
||||||
|
|
||||||
|
void setDeclared();
|
||||||
|
|
||||||
|
bool m_isDeclared;
|
||||||
|
|
||||||
|
std::string m_name;
|
||||||
|
std::vector<const Expression *> m_arguments;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
49
include/plasp/pddl/expressions/PredicateDeclaration.h
Normal file
49
include/plasp/pddl/expressions/PredicateDeclaration.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#ifndef __PLASP__PDDL__EXPRESSIONS__PREDICATE_DECLARATION_H
|
||||||
|
#define __PLASP__PDDL__EXPRESSIONS__PREDICATE_DECLARATION_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/Expression.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PredicateDeclaration
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class PredicateDeclaration: public ExpressionCRTP<PredicateDeclaration>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const Expression::Type ExpressionType = Expression::Type::PredicateDeclaration;
|
||||||
|
|
||||||
|
static void parse(Context &context, Domain &domain);
|
||||||
|
|
||||||
|
public:
|
||||||
|
const std::string &name() const;
|
||||||
|
const Variables &arguments() const;
|
||||||
|
|
||||||
|
bool isDeclared() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
PredicateDeclaration();
|
||||||
|
|
||||||
|
void setDeclared();
|
||||||
|
|
||||||
|
bool m_isDeclared;
|
||||||
|
|
||||||
|
std::string m_name;
|
||||||
|
Variables m_parameters;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
56
include/plasp/pddl/expressions/PrimitiveType.h
Normal file
56
include/plasp/pddl/expressions/PrimitiveType.h
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#ifndef __PLASP__PDDL__EXPRESSIONS__PRIMITIVE_TYPE_H
|
||||||
|
#define __PLASP__PDDL__EXPRESSIONS__PRIMITIVE_TYPE_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/ConsistencyException.h>
|
||||||
|
#include <plasp/pddl/Expression.h>
|
||||||
|
#include <plasp/pddl/Identifier.h>
|
||||||
|
#include <plasp/utils/ParserException.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PrimitiveType
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class PrimitiveType: public ExpressionCRTP<PrimitiveType>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const Expression::Type ExpressionType = Expression::Type::PrimitiveType;
|
||||||
|
|
||||||
|
static void parseDeclaration(Context &context, Domain &domain);
|
||||||
|
static void parseTypedDeclaration(Context &context, Domain &domain);
|
||||||
|
|
||||||
|
static PrimitiveType *parseAndFind(Context &context, Domain &domain);
|
||||||
|
|
||||||
|
public:
|
||||||
|
PrimitiveType();
|
||||||
|
PrimitiveType(std::string name);
|
||||||
|
|
||||||
|
const std::string &name() const;
|
||||||
|
const std::vector<const PrimitiveType *> &parentTypes() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setDirty(bool isDirty = true);
|
||||||
|
bool isDirty() const;
|
||||||
|
|
||||||
|
bool m_isDirty;
|
||||||
|
|
||||||
|
std::string m_name;
|
||||||
|
|
||||||
|
std::vector<const PrimitiveType *> m_parentTypes;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
28
include/plasp/pddl/expressions/Type.h
Normal file
28
include/plasp/pddl/expressions/Type.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef __PLASP__PDDL__EXPRESSIONS__TYPE_H
|
||||||
|
#define __PLASP__PDDL__EXPRESSIONS__TYPE_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/Expression.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Type
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const Expression *parseExistingPrimitiveType(Context &context,
|
||||||
|
ExpressionContext &expressionContext);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
40
include/plasp/pddl/expressions/Unsupported.h
Normal file
40
include/plasp/pddl/expressions/Unsupported.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#ifndef __PLASP__PDDL__EXPRESSIONS__UNSUPPORTED_H
|
||||||
|
#define __PLASP__PDDL__EXPRESSIONS__UNSUPPORTED_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/Expression.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Unsupported
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Unsupported: public ExpressionCRTP<Unsupported>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const Expression::Type ExpressionType = Expression::Type::Unsupported;
|
||||||
|
|
||||||
|
static UnsupportedPointer parse(Context &context);
|
||||||
|
|
||||||
|
public:
|
||||||
|
const std::string &type() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
61
include/plasp/pddl/expressions/Variable.h
Normal file
61
include/plasp/pddl/expressions/Variable.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#ifndef __PLASP__PDDL__EXPRESSIONS__VARIABLE_H
|
||||||
|
#define __PLASP__PDDL__EXPRESSIONS__VARIABLE_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/Expression.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Variable
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Variable: public ExpressionCRTP<Variable>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const Expression::Type ExpressionType = Expression::Type::Variable;
|
||||||
|
|
||||||
|
static void parseTypedDeclaration(Context &context, ExpressionContext &expressionContext);
|
||||||
|
static void parseTypedDeclarations(Context &context, ExpressionContext &expressionContext);
|
||||||
|
|
||||||
|
static const Variable *parseAndFind(Context &context,
|
||||||
|
const ExpressionContext &expressionContext);
|
||||||
|
|
||||||
|
public:
|
||||||
|
const std::string &name() const;
|
||||||
|
const Expression *type() const;
|
||||||
|
|
||||||
|
void setDirty(bool isDirty = true);
|
||||||
|
bool isDirty() const;
|
||||||
|
|
||||||
|
void setType(const Expression *type);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void parseDeclaration(Context &context, Variables ¶meters);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Variable();
|
||||||
|
|
||||||
|
bool m_isDirty;
|
||||||
|
|
||||||
|
std::string m_name;
|
||||||
|
|
||||||
|
const Expression *m_type;
|
||||||
|
|
||||||
|
// Stores "either" expression if necessary
|
||||||
|
ExpressionPointer m_eitherExpression;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <plasp/sas/Value.h>
|
#include <plasp/sas/Value.h>
|
||||||
#include <plasp/sas/Variable.h>
|
#include <plasp/sas/Variable.h>
|
||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
@@ -26,8 +27,8 @@ using AssignedVariables = std::vector<AssignedVariable>;
|
|||||||
class AssignedVariable
|
class AssignedVariable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static AssignedVariable fromSAS(std::istream &istream, const Variables &variables);
|
static AssignedVariable fromSAS(utils::Parser &parser, const Variables &variables);
|
||||||
static AssignedVariable fromSAS(std::istream &istream, const Variable &variable);
|
static AssignedVariable fromSAS(utils::Parser &parser, const Variable &variable);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AssignedVariable(const Variable &variable, const Value &value);
|
explicit AssignedVariable(const Variable &variable, const Value &value);
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <plasp/sas/AssignedVariable.h>
|
#include <plasp/sas/AssignedVariable.h>
|
||||||
#include <plasp/sas/Variable.h>
|
#include <plasp/sas/Variable.h>
|
||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
@@ -28,7 +29,7 @@ class AxiomRule
|
|||||||
using Condition = AssignedVariable;
|
using Condition = AssignedVariable;
|
||||||
using Conditions = AssignedVariables;
|
using Conditions = AssignedVariables;
|
||||||
|
|
||||||
static AxiomRule fromSAS(std::istream &istream, const Variables &variables);
|
static AxiomRule fromSAS(utils::Parser &parser, const Variables &variables);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const Conditions &conditions() const;
|
const Conditions &conditions() const;
|
||||||
|
@@ -16,7 +16,7 @@ namespace sas
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::ostream &operator >>(std::ostream &ostream, const Description &description);
|
utils::LogStream &operator<<(utils::LogStream &ostream, const Description &description);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
#include <plasp/sas/MutexGroup.h>
|
#include <plasp/sas/MutexGroup.h>
|
||||||
#include <plasp/sas/Operator.h>
|
#include <plasp/sas/Operator.h>
|
||||||
#include <plasp/sas/Variable.h>
|
#include <plasp/sas/Variable.h>
|
||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
@@ -28,6 +29,7 @@ namespace sas
|
|||||||
class Description
|
class Description
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static Description fromParser(utils::Parser &&parser);
|
||||||
static Description fromStream(std::istream &istream);
|
static Description fromStream(std::istream &istream);
|
||||||
static Description fromFile(const boost::filesystem::path &path);
|
static Description fromFile(const boost::filesystem::path &path);
|
||||||
|
|
||||||
@@ -46,14 +48,16 @@ class Description
|
|||||||
private:
|
private:
|
||||||
Description();
|
Description();
|
||||||
|
|
||||||
void parseVersionSection(std::istream &istream) const;
|
void parseContent(utils::Parser &parser);
|
||||||
void parseMetricSection(std::istream &istream);
|
|
||||||
void parseVariablesSection(std::istream &istream);
|
void parseVersionSection(utils::Parser &parser) const;
|
||||||
void parseMutexSection(std::istream &istream);
|
void parseMetricSection(utils::Parser &parser);
|
||||||
void parseInitialStateSection(std::istream &istream);
|
void parseVariablesSection(utils::Parser &parser);
|
||||||
void parseGoalSection(std::istream &istream);
|
void parseMutexSection(utils::Parser &parser);
|
||||||
void parseOperatorSection(std::istream &istream);
|
void parseInitialStateSection(utils::Parser &parser);
|
||||||
void parseAxiomSection(std::istream &istream);
|
void parseGoalSection(utils::Parser &parser);
|
||||||
|
void parseOperatorSection(utils::Parser &parser);
|
||||||
|
void parseAxiomSection(utils::Parser &parser);
|
||||||
|
|
||||||
bool m_usesActionCosts;
|
bool m_usesActionCosts;
|
||||||
|
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <plasp/sas/AssignedVariable.h>
|
#include <plasp/sas/AssignedVariable.h>
|
||||||
#include <plasp/sas/Variable.h>
|
#include <plasp/sas/Variable.h>
|
||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
@@ -28,7 +29,7 @@ class Effect
|
|||||||
using Condition = AssignedVariable;
|
using Condition = AssignedVariable;
|
||||||
using Conditions = AssignedVariables;
|
using Conditions = AssignedVariables;
|
||||||
|
|
||||||
static Effect fromSAS(std::istream &istream, const Variables &variables, Conditions &preconditions);
|
static Effect fromSAS(utils::Parser &parser, const Variables &variables, Conditions &preconditions);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const Conditions &conditions() const;
|
const Conditions &conditions() const;
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
#define __PLASP__SAS__GOAL_H
|
#define __PLASP__SAS__GOAL_H
|
||||||
|
|
||||||
#include <plasp/sas/AssignedVariable.h>
|
#include <plasp/sas/AssignedVariable.h>
|
||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
@@ -20,7 +21,7 @@ class Goal
|
|||||||
using Fact = AssignedVariable;
|
using Fact = AssignedVariable;
|
||||||
using Facts = AssignedVariables;
|
using Facts = AssignedVariables;
|
||||||
|
|
||||||
static Goal fromSAS(std::istream &istream, const Variables &variables);
|
static Goal fromSAS(utils::Parser &parser, const Variables &variables);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const Facts &facts() const;
|
const Facts &facts() const;
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
#define __PLASP__SAS__INITIAL_STATE_H
|
#define __PLASP__SAS__INITIAL_STATE_H
|
||||||
|
|
||||||
#include <plasp/sas/AssignedVariable.h>
|
#include <plasp/sas/AssignedVariable.h>
|
||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
@@ -20,7 +21,7 @@ class InitialState
|
|||||||
using Fact = AssignedVariable;
|
using Fact = AssignedVariable;
|
||||||
using Facts = AssignedVariables;
|
using Facts = AssignedVariables;
|
||||||
|
|
||||||
static InitialState fromSAS(std::istream &istream, const Variables &variables);
|
static InitialState fromSAS(utils::Parser &parser, const Variables &variables);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const Facts &facts() const;
|
const Facts &facts() const;
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <plasp/sas/AssignedVariable.h>
|
#include <plasp/sas/AssignedVariable.h>
|
||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
@@ -27,7 +28,7 @@ class MutexGroup
|
|||||||
using Fact = AssignedVariable;
|
using Fact = AssignedVariable;
|
||||||
using Facts = AssignedVariables;
|
using Facts = AssignedVariables;
|
||||||
|
|
||||||
static MutexGroup fromSAS(std::istream &istream, const Variables &variables);
|
static MutexGroup fromSAS(utils::Parser &parser, const Variables &variables);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const Facts &facts() const;
|
const Facts &facts() const;
|
||||||
|
@@ -8,6 +8,8 @@
|
|||||||
#include <plasp/sas/Effect.h>
|
#include <plasp/sas/Effect.h>
|
||||||
#include <plasp/sas/Predicate.h>
|
#include <plasp/sas/Predicate.h>
|
||||||
#include <plasp/sas/Variable.h>
|
#include <plasp/sas/Variable.h>
|
||||||
|
#include <plasp/utils/LogStream.h>
|
||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
@@ -31,10 +33,10 @@ class Operator
|
|||||||
using Condition = AssignedVariable;
|
using Condition = AssignedVariable;
|
||||||
using Conditions = AssignedVariables;
|
using Conditions = AssignedVariables;
|
||||||
|
|
||||||
static Operator fromSAS(std::istream &istream, const Variables &variables);
|
static Operator fromSAS(utils::Parser &parser, const Variables &variables);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void printPredicateAsASP(std::ostream &ostream) const;
|
void printPredicateAsASP(utils::LogStream &ostream) const;
|
||||||
|
|
||||||
const Predicate &predicate() const;
|
const Predicate &predicate() const;
|
||||||
const Conditions &preconditions() const;
|
const Conditions &preconditions() const;
|
||||||
|
@@ -5,6 +5,9 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <plasp/utils/LogStream.h>
|
||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
namespace sas
|
namespace sas
|
||||||
@@ -19,13 +22,13 @@ namespace sas
|
|||||||
class Predicate
|
class Predicate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static Predicate fromSAS(std::istream &istream);
|
static Predicate fromSAS(utils::Parser &parser);
|
||||||
|
|
||||||
using Arguments = std::vector<std::string>;
|
using Arguments = std::vector<std::string>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void printAsSAS(std::ostream &ostream) const;
|
void printAsSAS(utils::LogStream &outputStream) const;
|
||||||
void printAsASP(std::ostream &ostream) const;
|
void printAsASP(utils::LogStream &outputStream) const;
|
||||||
|
|
||||||
const std::string &name() const;
|
const std::string &name() const;
|
||||||
const Arguments &arguments() const;
|
const Arguments &arguments() const;
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
#define __PLASP__SAS__TRANSLATOR_ASP_H
|
#define __PLASP__SAS__TRANSLATOR_ASP_H
|
||||||
|
|
||||||
#include <plasp/sas/Description.h>
|
#include <plasp/sas/Description.h>
|
||||||
|
#include <plasp/utils/LogStream.h>
|
||||||
|
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
|
||||||
@@ -19,12 +20,21 @@ namespace sas
|
|||||||
class TranslatorASP
|
class TranslatorASP
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit TranslatorASP(const Description &description);
|
explicit TranslatorASP(const Description &description, utils::LogStream &outputStream);
|
||||||
|
|
||||||
void translate(std::ostream &ostream) const;
|
void translate() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void translateRequirements() const;
|
||||||
|
void translateInitialState() const;
|
||||||
|
void translateGoal() const;
|
||||||
|
void translateVariables() const;
|
||||||
|
void translateActions() const;
|
||||||
|
void translateMutexes() const;
|
||||||
|
void translateAxiomRules() const;
|
||||||
|
|
||||||
const Description &m_description;
|
const Description &m_description;
|
||||||
|
utils::LogStream &m_outputStream;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@@ -5,6 +5,9 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <plasp/utils/LogStream.h>
|
||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
namespace sas
|
namespace sas
|
||||||
@@ -36,15 +39,15 @@ struct Value
|
|||||||
static const Value Any;
|
static const Value Any;
|
||||||
static const Value None;
|
static const Value None;
|
||||||
|
|
||||||
static Value fromSAS(std::istream &istream);
|
static Value fromSAS(utils::Parser &parser);
|
||||||
static const Value &referenceFromSAS(std::istream &istream, const Variable &variable);
|
static const Value &referenceFromSAS(utils::Parser &parser, const Variable &variable);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Value negated() const;
|
Value negated() const;
|
||||||
|
|
||||||
void printAsSAS(std::ostream &ostream) const;
|
void printAsSAS(utils::LogStream &outputStream) const;
|
||||||
void printAsASP(std::ostream &ostream) const;
|
void printAsASP(utils::LogStream &outputStream) const;
|
||||||
void printAsASPPredicate(std::ostream &ostream) const;
|
void printAsASPPredicate(utils::LogStream &outputStream) const;
|
||||||
|
|
||||||
Sign sign() const;
|
Sign sign() const;
|
||||||
const std::string &name() const;
|
const std::string &name() const;
|
||||||
|
@@ -6,6 +6,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <plasp/sas/Value.h>
|
#include <plasp/sas/Value.h>
|
||||||
|
#include <plasp/utils/LogStream.h>
|
||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
@@ -26,11 +28,11 @@ using Variables = std::vector<Variable>;
|
|||||||
class Variable
|
class Variable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static Variable fromSAS(std::istream &istream);
|
static Variable fromSAS(utils::Parser &parser);
|
||||||
static const Variable &referenceFromSAS(std::istream &istream, const Variables &variables);
|
static const Variable &referenceFromSAS(utils::Parser &parser, const Variables &variables);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void printNameAsASPPredicate(std::ostream &ostream) const;
|
void printNameAsASPPredicate(utils::LogStream &outputStream) const;
|
||||||
|
|
||||||
const std::string &name() const;
|
const std::string &name() const;
|
||||||
int axiomLayer() const;
|
int axiomLayer() const;
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <plasp/sas/Value.h>
|
#include <plasp/sas/Value.h>
|
||||||
#include <plasp/sas/Variable.h>
|
#include <plasp/sas/Variable.h>
|
||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
@@ -25,7 +26,7 @@ using VariableTransitions = std::vector<VariableTransition>;
|
|||||||
class VariableTransition
|
class VariableTransition
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static VariableTransition fromSAS(std::istream &istream, const Variables &variables);
|
static VariableTransition fromSAS(utils::Parser &parser, const Variables &variables);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const Variable &variable() const;
|
const Variable &variable() const;
|
||||||
|
203
include/plasp/utils/Formatting.h
Normal file
203
include/plasp/utils/Formatting.h
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
#ifndef __PLASP__UTILS__FORMATTING_H
|
||||||
|
#define __PLASP__UTILS__FORMATTING_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <plasp/utils/LogStream.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace utils
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Formatting
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
enum class Color
|
||||||
|
{
|
||||||
|
Black = 0,
|
||||||
|
Red = 1,
|
||||||
|
Green = 2,
|
||||||
|
Yellow = 3,
|
||||||
|
Blue = 4,
|
||||||
|
Magenta = 5,
|
||||||
|
Cyan = 6,
|
||||||
|
White = 7
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
enum class FontWeight
|
||||||
|
{
|
||||||
|
Normal = 0,
|
||||||
|
Bold = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct Format
|
||||||
|
{
|
||||||
|
Format(Color color, FontWeight fontWeight = FontWeight::Normal)
|
||||||
|
: m_color{color},
|
||||||
|
m_fontWeight{fontWeight}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Color m_color;
|
||||||
|
FontWeight m_fontWeight;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
inline LogStream &operator<<(LogStream &stream, const Format &format)
|
||||||
|
{
|
||||||
|
if (!stream.supportsColor())
|
||||||
|
return stream;
|
||||||
|
|
||||||
|
const auto fontWeightCode = static_cast<size_t>(format.m_fontWeight);
|
||||||
|
const auto colorCode = 30 + static_cast<size_t>(format.m_color);
|
||||||
|
|
||||||
|
return (stream << "\033[" << fontWeightCode << ";" << colorCode << "m");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct ResetFormat
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
inline LogStream &operator<<(LogStream &stream, const ResetFormat &)
|
||||||
|
{
|
||||||
|
if (!stream.supportsColor())
|
||||||
|
return stream;
|
||||||
|
|
||||||
|
return (stream << "\033[0m");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct Token
|
||||||
|
{
|
||||||
|
Token(const std::string &name)
|
||||||
|
: name(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string &name;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct Keyword: public Token
|
||||||
|
{
|
||||||
|
Keyword(const std::string &name)
|
||||||
|
: Token(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
inline LogStream &operator<<(LogStream &stream, const Keyword &keyword)
|
||||||
|
{
|
||||||
|
return (stream
|
||||||
|
<< utils::Format(utils::Color::White, utils::FontWeight::Bold)
|
||||||
|
<< 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::Bold)
|
||||||
|
<< number.name
|
||||||
|
<< utils::ResetFormat());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct Variable: public Token
|
||||||
|
{
|
||||||
|
Variable(const std::string &name)
|
||||||
|
: Token(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
inline LogStream &operator<<(LogStream &stream, const Variable &variable)
|
||||||
|
{
|
||||||
|
return (stream
|
||||||
|
<< utils::Format(utils::Color::Green, utils::FontWeight::Bold)
|
||||||
|
<< variable.name
|
||||||
|
<< utils::ResetFormat());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct Heading1: public Token
|
||||||
|
{
|
||||||
|
Heading1(const std::string &name)
|
||||||
|
: Token(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
inline LogStream &operator<<(LogStream &stream, const Heading1 &heading1)
|
||||||
|
{
|
||||||
|
return (stream
|
||||||
|
<< utils::Format(utils::Color::Blue, utils::FontWeight::Bold)
|
||||||
|
<< "%---------------------------------------" << std::endl
|
||||||
|
<< "% " << heading1.name << std::endl
|
||||||
|
<< "%---------------------------------------"
|
||||||
|
<< utils::ResetFormat()
|
||||||
|
<< std::endl);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct Heading2: public Token
|
||||||
|
{
|
||||||
|
Heading2(const std::string &name)
|
||||||
|
: Token(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
inline LogStream &operator<<(LogStream &stream, const Heading2 &heading2)
|
||||||
|
{
|
||||||
|
return (stream
|
||||||
|
<< utils::Format(utils::Color::Blue, utils::FontWeight::Bold)
|
||||||
|
<< "% " << heading2.name
|
||||||
|
<< utils::ResetFormat());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@@ -1,17 +1,8 @@
|
|||||||
#ifndef __PLASP__UTILS__PARSING_H
|
#ifndef __PLASP__UTILS__IO_H
|
||||||
#define __PLASP__UTILS__PARSING_H
|
#define __PLASP__UTILS__IO_H
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <exception>
|
|
||||||
#include <iosfwd>
|
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
|
||||||
#include <typeinfo>
|
|
||||||
|
|
||||||
#include <boost/algorithm/string/replace.hpp>
|
#include <boost/algorithm/string/replace.hpp>
|
||||||
|
|
||||||
#include <plasp/utils/ParserException.h>
|
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
namespace utils
|
namespace utils
|
||||||
@@ -19,46 +10,10 @@ namespace utils
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Parsing
|
// IO
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class T>
|
|
||||||
T parse(std::istream &istream)
|
|
||||||
{
|
|
||||||
T value;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
istream >> value;
|
|
||||||
}
|
|
||||||
catch (const std::exception &e)
|
|
||||||
{
|
|
||||||
throw ParserException(std::string("Could not parse value of type ") + typeid(T).name() + " (" + e.what() + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
void parseExpected(std::istream &istream, const T &expectedValue)
|
|
||||||
{
|
|
||||||
const auto value = parse<T>(istream);
|
|
||||||
|
|
||||||
if (value == expectedValue)
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::stringstream errorStream;
|
|
||||||
|
|
||||||
errorStream << "Invalid format, expected " << expectedValue << ", got " + value;
|
|
||||||
|
|
||||||
throw utils::ParserException(errorStream.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline std::string escapeASP(const std::string &string)
|
inline std::string escapeASP(const std::string &string)
|
||||||
{
|
{
|
||||||
auto escaped = string;
|
auto escaped = string;
|
||||||
@@ -85,6 +40,17 @@ inline std::string unescapeASP(const std::string &string)
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
inline std::string escapeASPVariable(const std::string &string)
|
||||||
|
{
|
||||||
|
auto escaped = escapeASP(string);
|
||||||
|
|
||||||
|
escaped.front() = std::toupper(escaped.front());
|
||||||
|
|
||||||
|
return escaped;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
289
include/plasp/utils/LogStream.h
Normal file
289
include/plasp/utils/LogStream.h
Normal file
@@ -0,0 +1,289 @@
|
|||||||
|
#ifndef __PLASP__UTILS__LOG_STREAM_H
|
||||||
|
#define __PLASP__UTILS__LOG_STREAM_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
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<<(std::basic_streambuf<CharacterType, TraitsType> *sb);
|
||||||
|
inline LogStream &operator<<(std::ios_base &(*func)(std::ios_base &));
|
||||||
|
inline LogStream &operator<<(std::basic_ios<CharacterType, TraitsType> &(*func)(std::basic_ios<CharacterType, TraitsType> &));
|
||||||
|
inline LogStream &operator<<(std::basic_ostream<CharacterType, TraitsType> &(*func)(std::basic_ostream<CharacterType, TraitsType> &));
|
||||||
|
|
||||||
|
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<<(std::basic_streambuf<CharacterType, TraitsType>* 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<CharacterType, TraitsType> &(*func)(std::basic_ios<CharacterType, TraitsType> &))
|
||||||
|
{
|
||||||
|
ostream() << func;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
LogStream &LogStream::operator<<(std::basic_ostream<CharacterType, TraitsType> &(*func)(std::basic_ostream<CharacterType, TraitsType> &))
|
||||||
|
{
|
||||||
|
ostream() << func;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class CharacterType, class Traits, class Allocator>
|
||||||
|
inline LogStream &operator<<(LogStream &stream, const std::basic_string<CharacterType, Traits, Allocator> &string)
|
||||||
|
{
|
||||||
|
stream.ostream() << string;
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
62
include/plasp/utils/Logger.h
Normal file
62
include/plasp/utils/Logger.h
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#ifndef __PLASP__UTILS__LOGGER_H
|
||||||
|
#define __PLASP__UTILS__LOGGER_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <plasp/utils/LogStream.h>
|
||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
#include <plasp/utils/ParserException.h>
|
||||||
|
|
||||||
|
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 Parser::Coordinate &coordinate, const std::string &message);
|
||||||
|
void logWarning(const Parser &parser, const std::string &message);
|
||||||
|
|
||||||
|
private:
|
||||||
|
LogStream m_outputStream;
|
||||||
|
LogStream m_errorStream;
|
||||||
|
|
||||||
|
WarningLevel m_warningLevel;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
167
include/plasp/utils/Parser.h
Normal file
167
include/plasp/utils/Parser.h
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
#ifndef __PLASP__UTILS__PARSER_H
|
||||||
|
#define __PLASP__UTILS__PARSER_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <iterator>
|
||||||
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace utils
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Parser
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Parser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using Position = std::stringstream::pos_type;
|
||||||
|
|
||||||
|
struct Coordinate
|
||||||
|
{
|
||||||
|
std::string sectionName;
|
||||||
|
size_t row;
|
||||||
|
size_t column;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StreamDelimiter
|
||||||
|
{
|
||||||
|
Position position;
|
||||||
|
std::string sectionName;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Parser();
|
||||||
|
explicit Parser(std::string streamName, std::istream &istream);
|
||||||
|
|
||||||
|
// Forbid copy construction/assignment
|
||||||
|
Parser(const Parser &other) = delete;
|
||||||
|
Parser &operator=(const Parser &other) = delete;
|
||||||
|
|
||||||
|
Parser(Parser &&other);
|
||||||
|
Parser &operator=(Parser &&other);
|
||||||
|
|
||||||
|
void readStream(std::string streamName, std::istream &istream);
|
||||||
|
void readFile(const boost::filesystem::path &path);
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
void seek(Position position);
|
||||||
|
Position position() const;
|
||||||
|
Coordinate coordinate() const;
|
||||||
|
|
||||||
|
void setCaseSensitive(bool isCaseInsensitive = true);
|
||||||
|
|
||||||
|
char currentCharacter() const;
|
||||||
|
void advance();
|
||||||
|
bool atEndOfStream() const;
|
||||||
|
|
||||||
|
void removeComments(const std::string &startSequence, const std::string &endSequence, bool removeEnd);
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
Type parse();
|
||||||
|
|
||||||
|
template<class CharacterPredicate, class WhiteSpacePredicate>
|
||||||
|
std::string parseIdentifier(CharacterPredicate characterPredicate, WhiteSpacePredicate whiteSpacePredicate);
|
||||||
|
|
||||||
|
template<class CharacterPredicate>
|
||||||
|
std::string parseIdentifier(CharacterPredicate characterPredicate);
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
bool probe(const Type &expectedValue);
|
||||||
|
|
||||||
|
template<class CharacterPredicate>
|
||||||
|
bool probeIdentifier(const std::string &identifier, CharacterPredicate characterPredicate);
|
||||||
|
|
||||||
|
bool probeNumber();
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
void expect(const Type &expectedValue);
|
||||||
|
|
||||||
|
template<class WhiteSpacePredicate>
|
||||||
|
void skipWhiteSpace(WhiteSpacePredicate whiteSpacePredicate);
|
||||||
|
|
||||||
|
void skipWhiteSpace();
|
||||||
|
void skipLine();
|
||||||
|
|
||||||
|
std::string getLine();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const std::istreambuf_iterator<char> EndOfFile;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void checkStream() const;
|
||||||
|
|
||||||
|
uint64_t parseIntegerBody();
|
||||||
|
|
||||||
|
mutable std::stringstream m_stream;
|
||||||
|
|
||||||
|
std::vector<StreamDelimiter> m_streamDelimiters;
|
||||||
|
|
||||||
|
bool m_isCaseSensitive;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class CharacterPredicate, class WhiteSpacePredicate>
|
||||||
|
std::string Parser::parseIdentifier(CharacterPredicate characterPredicate, WhiteSpacePredicate whiteSpacePredicate)
|
||||||
|
{
|
||||||
|
skipWhiteSpace(whiteSpacePredicate);
|
||||||
|
|
||||||
|
std::string value;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
const auto character = currentCharacter();
|
||||||
|
|
||||||
|
if (!characterPredicate(character))
|
||||||
|
return value;
|
||||||
|
|
||||||
|
value.push_back(character);
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class CharacterPredicate>
|
||||||
|
std::string Parser::parseIdentifier(CharacterPredicate characterPredicate)
|
||||||
|
{
|
||||||
|
return parseIdentifier(characterPredicate,
|
||||||
|
[&](const auto character)
|
||||||
|
{
|
||||||
|
return std::isspace(character);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class CharacterPredicate>
|
||||||
|
bool Parser::probeIdentifier(const std::string &expectedValue, CharacterPredicate characterPredicate)
|
||||||
|
{
|
||||||
|
return probe<std::string>(expectedValue) && !characterPredicate(currentCharacter());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class WhiteSpacePredicate>
|
||||||
|
void Parser::skipWhiteSpace(WhiteSpacePredicate whiteSpacePredicate)
|
||||||
|
{
|
||||||
|
checkStream();
|
||||||
|
|
||||||
|
while (!atEndOfStream() && whiteSpacePredicate(currentCharacter()))
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@@ -4,6 +4,8 @@
|
|||||||
#include <exception>
|
#include <exception>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
namespace utils
|
namespace utils
|
||||||
@@ -18,17 +20,21 @@ namespace utils
|
|||||||
class ParserException: public std::exception
|
class ParserException: public std::exception
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ParserException()
|
explicit ParserException(const utils::Parser &parser)
|
||||||
|
: ParserException(parser, "unspecified parser error")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit ParserException(const char *message)
|
explicit ParserException(const utils::Parser &parser, const char *message)
|
||||||
: m_message(message)
|
: ParserException(parser, static_cast<std::string>(message))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit ParserException(const std::string &message)
|
explicit ParserException(const utils::Parser &parser, const std::string &message)
|
||||||
: m_message(message)
|
: m_coordinate{parser.coordinate()},
|
||||||
|
m_message{message},
|
||||||
|
m_plainMessage{m_coordinate.sectionName + ":" + std::to_string(m_coordinate.row)
|
||||||
|
+ ":" + std::to_string(m_coordinate.column) + " " + m_message}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,14 +44,23 @@ class ParserException: public std::exception
|
|||||||
|
|
||||||
const char *what() const throw()
|
const char *what() const throw()
|
||||||
{
|
{
|
||||||
if (m_message.empty())
|
return m_plainMessage.c_str();
|
||||||
return "Unspecified error while parsing SAS description file";
|
}
|
||||||
|
|
||||||
return m_message.c_str();
|
const Parser::Coordinate &coordinate() const
|
||||||
|
{
|
||||||
|
return m_coordinate;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string &message() const
|
||||||
|
{
|
||||||
|
return m_message;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Parser::Coordinate m_coordinate;
|
||||||
std::string m_message;
|
std::string m_message;
|
||||||
|
std::string m_plainMessage;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
#ifndef __PLASP__SAS__TRANSLATOR_EXCEPTION_H
|
#ifndef __PLASP__UTILS__TRANSLATOR_EXCEPTION_H
|
||||||
#define __PLASP__SAS__TRANSLATOR_EXCEPTION_H
|
#define __PLASP__UTILS__TRANSLATOR_EXCEPTION_H
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
namespace sas
|
namespace utils
|
||||||
{
|
{
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -39,7 +39,7 @@ class TranslatorException: public std::exception
|
|||||||
const char *what() const throw()
|
const char *what() const throw()
|
||||||
{
|
{
|
||||||
if (m_message.empty())
|
if (m_message.empty())
|
||||||
return "Unspecified error while translating SAS description";
|
return "Unspecified error while translating description";
|
||||||
|
|
||||||
return m_message.c_str();
|
return m_message.c_str();
|
||||||
}
|
}
|
@@ -3,6 +3,12 @@ set(target plasp)
|
|||||||
file(GLOB core_sources "plasp/*.cpp")
|
file(GLOB core_sources "plasp/*.cpp")
|
||||||
file(GLOB core_headers "../include/plasp/*.h")
|
file(GLOB core_headers "../include/plasp/*.h")
|
||||||
|
|
||||||
|
file(GLOB pddl_sources "plasp/pddl/*.cpp")
|
||||||
|
file(GLOB pddl_headers "../include/plasp/pddl/*.h")
|
||||||
|
|
||||||
|
file(GLOB pddl_expressions_sources "plasp/pddl/expressions/*.cpp")
|
||||||
|
file(GLOB pddl_expressions_headers "../include/plasp/pddl/expressions/*.h")
|
||||||
|
|
||||||
file(GLOB sas_sources "plasp/sas/*.cpp")
|
file(GLOB sas_sources "plasp/sas/*.cpp")
|
||||||
file(GLOB sas_headers "../include/plasp/sas/*.h")
|
file(GLOB sas_headers "../include/plasp/sas/*.h")
|
||||||
|
|
||||||
@@ -21,6 +27,12 @@ set(sources
|
|||||||
${core_sources}
|
${core_sources}
|
||||||
${core_headers}
|
${core_headers}
|
||||||
|
|
||||||
|
${pddl_sources}
|
||||||
|
${pddl_headers}
|
||||||
|
|
||||||
|
${pddl_expressions_sources}
|
||||||
|
${pddl_expressions_headers}
|
||||||
|
|
||||||
${sas_sources}
|
${sas_sources}
|
||||||
${sas_headers}
|
${sas_headers}
|
||||||
|
|
||||||
|
50
src/plasp/Language.cpp
Normal file
50
src/plasp/Language.cpp
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#include <plasp/Language.h>
|
||||||
|
|
||||||
|
#include <boost/assign.hpp>
|
||||||
|
#include <boost/bimap.hpp>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Language
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
using LanguageNames = boost::bimap<Language::Type, std::string>;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const LanguageNames languageNames = boost::assign::list_of<LanguageNames::relation>
|
||||||
|
(Language::Type::PDDL, "pddl")
|
||||||
|
(Language::Type::SAS, "sas")
|
||||||
|
(Language::Type::Unknown, "unknown");
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::string Language::toString(Language::Type language)
|
||||||
|
{
|
||||||
|
const auto match = languageNames.left.find(language);
|
||||||
|
|
||||||
|
if (match == languageNames.left.end())
|
||||||
|
return "unknown";
|
||||||
|
|
||||||
|
return match->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Language::Type Language::fromString(const std::string &languageName)
|
||||||
|
{
|
||||||
|
const auto match = languageNames.right.find(languageName);
|
||||||
|
|
||||||
|
if (match == languageNames.right.end())
|
||||||
|
return Language::Type::Unknown;
|
||||||
|
|
||||||
|
return match->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
92
src/plasp/pddl/Action.cpp
Normal file
92
src/plasp/pddl/Action.cpp
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
#include <plasp/pddl/Action.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/Domain.h>
|
||||||
|
#include <plasp/pddl/ExpressionContext.h>
|
||||||
|
#include <plasp/pddl/Identifier.h>
|
||||||
|
#include <plasp/pddl/expressions/Type.h>
|
||||||
|
#include <plasp/utils/IO.h>
|
||||||
|
#include <plasp/utils/ParserException.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Action
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Action::parseDeclaration(Context &context, Domain &domain)
|
||||||
|
{
|
||||||
|
auto action = std::make_unique<Action>(Action());
|
||||||
|
|
||||||
|
action->m_name = context.parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
context.parser.expect<std::string>(":parameters");
|
||||||
|
context.parser.expect<std::string>("(");
|
||||||
|
|
||||||
|
ExpressionContext expressionContext(domain, action->m_parameters);
|
||||||
|
|
||||||
|
// Read parameters
|
||||||
|
expressions::Variable::parseTypedDeclarations(context, expressionContext);
|
||||||
|
|
||||||
|
context.parser.expect<std::string>(")");
|
||||||
|
|
||||||
|
// Parse preconditions and effects
|
||||||
|
while (context.parser.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
context.parser.expect<std::string>(":");
|
||||||
|
|
||||||
|
if (context.parser.probeIdentifier("precondition", isIdentifier))
|
||||||
|
action->m_precondition = parsePreconditionExpression(context, expressionContext);
|
||||||
|
else if (context.parser.probeIdentifier("effect", isIdentifier))
|
||||||
|
action->m_effect = parseEffectExpression(context, expressionContext);
|
||||||
|
|
||||||
|
context.parser.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store new action
|
||||||
|
expressionContext.domain.actions().emplace_back(std::move(action));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::string &Action::name() const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const expressions::Variables &Action::parameters() const
|
||||||
|
{
|
||||||
|
return m_parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const Expression *Action::precondition() const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(m_precondition);
|
||||||
|
|
||||||
|
return m_precondition.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const Expression *Action::effect() const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(m_effect);
|
||||||
|
|
||||||
|
return m_effect.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
209
src/plasp/pddl/Description.cpp
Normal file
209
src/plasp/pddl/Description.cpp
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
#include <plasp/pddl/Description.h>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
#include <plasp/pddl/IO.h>
|
||||||
|
#include <plasp/utils/ParserException.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Description
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Description::Description()
|
||||||
|
: m_domainPosition{-1},
|
||||||
|
m_domain{std::make_unique<Domain>(Domain(m_context))},
|
||||||
|
m_problemPosition{-1}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Description Description::fromContext(Context &&context)
|
||||||
|
{
|
||||||
|
Description description;
|
||||||
|
|
||||||
|
description.m_context = std::move(context);
|
||||||
|
description.parse();
|
||||||
|
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Description Description::fromStream(std::istream &istream)
|
||||||
|
{
|
||||||
|
Description description;
|
||||||
|
|
||||||
|
description.m_context.parser.readStream("std::cin", istream);
|
||||||
|
description.parse();
|
||||||
|
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Description Description::fromFile(const std::string &path)
|
||||||
|
{
|
||||||
|
Description description;
|
||||||
|
|
||||||
|
description.m_context.parser.readFile(path);
|
||||||
|
description.parse();
|
||||||
|
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Description Description::fromFiles(const std::vector<std::string> &paths)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(!paths.empty());
|
||||||
|
|
||||||
|
Description description;
|
||||||
|
|
||||||
|
std::for_each(paths.cbegin(), paths.cend(),
|
||||||
|
[&](const auto &path)
|
||||||
|
{
|
||||||
|
description.m_context.parser.readFile(path);
|
||||||
|
});
|
||||||
|
|
||||||
|
description.parse();
|
||||||
|
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Context &Description::context()
|
||||||
|
{
|
||||||
|
return m_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const Context &Description::context() const
|
||||||
|
{
|
||||||
|
return m_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const Domain &Description::domain() const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(m_domain);
|
||||||
|
|
||||||
|
return *m_domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool Description::containsProblem() const
|
||||||
|
{
|
||||||
|
return m_problem.get() != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const Problem &Description::problem() const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(m_problem);
|
||||||
|
|
||||||
|
return *m_problem;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Description::parse()
|
||||||
|
{
|
||||||
|
auto &parser = m_context.parser;
|
||||||
|
|
||||||
|
parser.setCaseSensitive(false);
|
||||||
|
parser.removeComments(";", "\n", false);
|
||||||
|
|
||||||
|
// First, determine the locations of domain and problem
|
||||||
|
findSections();
|
||||||
|
|
||||||
|
if (m_domainPosition == -1)
|
||||||
|
throw ConsistencyException("no PDDL domain specified");
|
||||||
|
|
||||||
|
parser.seek(m_domainPosition);
|
||||||
|
m_domain->parse();
|
||||||
|
|
||||||
|
if (m_problemPosition != -1)
|
||||||
|
{
|
||||||
|
parser.seek(m_problemPosition);
|
||||||
|
m_problem->parse();
|
||||||
|
}
|
||||||
|
|
||||||
|
checkConsistency();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Description::findSections()
|
||||||
|
{
|
||||||
|
auto &parser = m_context.parser;
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
while (!parser.atEndOfStream())
|
||||||
|
{
|
||||||
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>("define");
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
|
||||||
|
if (parser.probe<std::string>("domain"))
|
||||||
|
{
|
||||||
|
if (m_domainPosition != -1)
|
||||||
|
throw utils::ParserException(parser, "PDDL description may not contain two domains");
|
||||||
|
|
||||||
|
m_domainPosition = position;
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
m_domain->findSections();
|
||||||
|
}
|
||||||
|
else if (m_context.parser.probe<std::string>("problem"))
|
||||||
|
{
|
||||||
|
if (m_problemPosition != -1)
|
||||||
|
throw utils::ParserException(parser, "PDDL description may currently not contain two problems");
|
||||||
|
|
||||||
|
m_problem = std::make_unique<Problem>(Problem(m_context, *m_domain));
|
||||||
|
|
||||||
|
m_problemPosition = position;
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
m_problem->findSections();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto sectionIdentifier = parser.parse<std::string>();
|
||||||
|
throw utils::ParserException(parser, "unknown PDDL section “" + sectionIdentifier + "”");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_context.parser.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Description::checkConsistency()
|
||||||
|
{
|
||||||
|
m_domain->checkConsistency();
|
||||||
|
m_problem->checkConsistency();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
419
src/plasp/pddl/Domain.cpp
Normal file
419
src/plasp/pddl/Domain.cpp
Normal file
@@ -0,0 +1,419 @@
|
|||||||
|
#include <plasp/pddl/Domain.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <plasp/pddl/ConsistencyException.h>
|
||||||
|
#include <plasp/pddl/Identifier.h>
|
||||||
|
#include <plasp/pddl/IO.h>
|
||||||
|
#include <plasp/pddl/expressions/Constant.h>
|
||||||
|
#include <plasp/pddl/expressions/PredicateDeclaration.h>
|
||||||
|
#include <plasp/pddl/expressions/PrimitiveType.h>
|
||||||
|
#include <plasp/pddl/expressions/Variable.h>
|
||||||
|
#include <plasp/utils/IO.h>
|
||||||
|
#include <plasp/utils/ParserException.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Domain
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Domain::Domain(Context &context)
|
||||||
|
: m_context(context),
|
||||||
|
m_requirementsPosition{-1},
|
||||||
|
m_typesPosition{-1},
|
||||||
|
m_constantsPosition{-1},
|
||||||
|
m_predicatesPosition{-1}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Domain::findSections()
|
||||||
|
{
|
||||||
|
auto &parser = m_context.parser;
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>("define");
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>("domain");
|
||||||
|
|
||||||
|
m_name = m_context.parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
|
||||||
|
const auto setSectionPosition =
|
||||||
|
[&](const std::string §ionName, auto §ionPosition, const auto value, bool unique = false)
|
||||||
|
{
|
||||||
|
if (unique && sectionPosition != -1)
|
||||||
|
{
|
||||||
|
parser.seek(value);
|
||||||
|
throw utils::ParserException(parser, "only one “:" + sectionName + "” section allowed");
|
||||||
|
}
|
||||||
|
|
||||||
|
sectionPosition = value;
|
||||||
|
};
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
// Find sections
|
||||||
|
while (parser.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>(":");
|
||||||
|
|
||||||
|
const auto sectionIdentifierPosition = parser.position();
|
||||||
|
|
||||||
|
// Save the parser position of the individual sections for later parsing
|
||||||
|
if (parser.probeIdentifier("requirements", isIdentifier))
|
||||||
|
setSectionPosition("requirements", m_requirementsPosition, position, true);
|
||||||
|
else if (parser.probeIdentifier("types", isIdentifier))
|
||||||
|
setSectionPosition("types", m_typesPosition, position, true);
|
||||||
|
else if (parser.probeIdentifier("constants", isIdentifier))
|
||||||
|
setSectionPosition("constants", m_constantsPosition, position, true);
|
||||||
|
else if (parser.probeIdentifier("predicates", isIdentifier))
|
||||||
|
setSectionPosition("predicates", m_predicatesPosition, position, true);
|
||||||
|
else if (parser.probeIdentifier("action", isIdentifier))
|
||||||
|
{
|
||||||
|
m_actionPositions.emplace_back(-1);
|
||||||
|
setSectionPosition("action", m_actionPositions.back(), position);
|
||||||
|
}
|
||||||
|
else if (parser.probeIdentifier("functions", isIdentifier)
|
||||||
|
|| parser.probeIdentifier("constraints", isIdentifier)
|
||||||
|
|| parser.probeIdentifier("durative-action", isIdentifier)
|
||||||
|
|| parser.probeIdentifier("derived", isIdentifier))
|
||||||
|
{
|
||||||
|
parser.seek(sectionIdentifierPosition);
|
||||||
|
|
||||||
|
const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
m_context.logger.logWarning(parser, "section type “" + sectionIdentifier + "” currently unsupported");
|
||||||
|
|
||||||
|
parser.seek(sectionIdentifierPosition);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
throw utils::ParserException(m_context.parser, "unknown domain section “" + sectionIdentifier + "”");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip section for now and parse it later
|
||||||
|
skipSection(parser);
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Domain::parse()
|
||||||
|
{
|
||||||
|
auto &parser = m_context.parser;
|
||||||
|
|
||||||
|
if (m_requirementsPosition != -1)
|
||||||
|
{
|
||||||
|
parser.seek(m_requirementsPosition);
|
||||||
|
parseRequirementSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_typesPosition != -1)
|
||||||
|
{
|
||||||
|
parser.seek(m_typesPosition);
|
||||||
|
parseTypeSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_constantsPosition != -1)
|
||||||
|
{
|
||||||
|
parser.seek(m_constantsPosition);
|
||||||
|
parseConstantSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_predicatesPosition != -1)
|
||||||
|
{
|
||||||
|
parser.seek(m_predicatesPosition);
|
||||||
|
parsePredicateSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < m_actionPositions.size(); i++)
|
||||||
|
if (m_actionPositions[i] != -1)
|
||||||
|
{
|
||||||
|
parser.seek(m_actionPositions[i]);
|
||||||
|
parseActionSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
computeDerivedRequirements();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Domain::setName(std::string name)
|
||||||
|
{
|
||||||
|
m_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::string &Domain::name() const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const Requirements &Domain::requirements() const
|
||||||
|
{
|
||||||
|
return m_requirements;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
expressions::PrimitiveTypes &Domain::types()
|
||||||
|
{
|
||||||
|
return m_types;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const expressions::PrimitiveTypes &Domain::types() const
|
||||||
|
{
|
||||||
|
return m_types;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
expressions::Constants &Domain::constants()
|
||||||
|
{
|
||||||
|
return m_constants;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const expressions::Constants &Domain::constants() const
|
||||||
|
{
|
||||||
|
return m_constants;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
expressions::PredicateDeclarations &Domain::predicates()
|
||||||
|
{
|
||||||
|
return m_predicates;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const expressions::PredicateDeclarations &Domain::predicates() const
|
||||||
|
{
|
||||||
|
return m_predicates;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<Action>> &Domain::actions()
|
||||||
|
{
|
||||||
|
return m_actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::vector<std::unique_ptr<Action>> &Domain::actions() const
|
||||||
|
{
|
||||||
|
return m_actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Domain::parseRequirementSection()
|
||||||
|
{
|
||||||
|
auto &parser = m_context.parser;
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>(":");
|
||||||
|
parser.expect<std::string>("requirements");
|
||||||
|
|
||||||
|
while (parser.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
parser.expect<std::string>(":");
|
||||||
|
|
||||||
|
m_requirements.emplace_back(Requirement::parse(m_context));
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: do this check only once the problem is parsed
|
||||||
|
// If no requirements are specified, assume STRIPS
|
||||||
|
if (m_requirements.empty())
|
||||||
|
m_requirements.emplace_back(Requirement::Type::STRIPS);
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool Domain::hasRequirement(Requirement::Type requirementType) const
|
||||||
|
{
|
||||||
|
const auto match = std::find_if(m_requirements.cbegin(), m_requirements.cend(),
|
||||||
|
[&](const auto &requirement)
|
||||||
|
{
|
||||||
|
return requirement.type() == requirementType;
|
||||||
|
});
|
||||||
|
|
||||||
|
return match != m_requirements.cend();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Domain::checkRequirement(Requirement::Type requirementType) const
|
||||||
|
{
|
||||||
|
if (hasRequirement(requirementType))
|
||||||
|
return;
|
||||||
|
|
||||||
|
throw ConsistencyException("requirement “" + Requirement(requirementType).toPDDL() + "” used but never declared");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Domain::computeDerivedRequirements()
|
||||||
|
{
|
||||||
|
const auto addRequirementUnique =
|
||||||
|
[&](const auto requirement)
|
||||||
|
{
|
||||||
|
if (hasRequirement(requirement))
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_requirements.push_back(Requirement(requirement));
|
||||||
|
};
|
||||||
|
|
||||||
|
if (hasRequirement(Requirement::Type::ADL))
|
||||||
|
{
|
||||||
|
addRequirementUnique(Requirement::Type::STRIPS);
|
||||||
|
addRequirementUnique(Requirement::Type::Typing);
|
||||||
|
addRequirementUnique(Requirement::Type::NegativePreconditions);
|
||||||
|
addRequirementUnique(Requirement::Type::DisjunctivePreconditions);
|
||||||
|
addRequirementUnique(Requirement::Type::Equality);
|
||||||
|
addRequirementUnique(Requirement::Type::QuantifiedPreconditions);
|
||||||
|
addRequirementUnique(Requirement::Type::ConditionalEffects);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasRequirement(Requirement::Type::QuantifiedPreconditions))
|
||||||
|
{
|
||||||
|
addRequirementUnique(Requirement::Type::ExistentialPreconditions);
|
||||||
|
addRequirementUnique(Requirement::Type::UniversalPreconditions);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasRequirement(Requirement::Type::Fluents))
|
||||||
|
{
|
||||||
|
addRequirementUnique(Requirement::Type::NumericFluents);
|
||||||
|
addRequirementUnique(Requirement::Type::ObjectFluents);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasRequirement(Requirement::Type::TimedInitialLiterals))
|
||||||
|
addRequirementUnique(Requirement::Type::DurativeActions);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Domain::parseTypeSection()
|
||||||
|
{
|
||||||
|
auto &parser = m_context.parser;
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>(":");
|
||||||
|
parser.expect<std::string>("types");
|
||||||
|
|
||||||
|
checkRequirement(Requirement::Type::Typing);
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
// Store types and their parent types
|
||||||
|
while (parser.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
if (parser.currentCharacter() == '(')
|
||||||
|
throw utils::ParserException(parser, "only primitive types are allowed in type section");
|
||||||
|
|
||||||
|
expressions::PrimitiveType::parseTypedDeclaration(m_context, *this);
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Domain::parseConstantSection()
|
||||||
|
{
|
||||||
|
auto &parser = m_context.parser;
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>(":");
|
||||||
|
parser.expect<std::string>("constants");
|
||||||
|
|
||||||
|
// Store constants
|
||||||
|
expressions::Constant::parseTypedDeclarations(m_context, *this);
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Domain::parsePredicateSection()
|
||||||
|
{
|
||||||
|
auto &parser = m_context.parser;
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>(":");
|
||||||
|
parser.expect<std::string>("predicates");
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
// Store predicates and their arguments
|
||||||
|
while (parser.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
expressions::PredicateDeclaration::parse(m_context, *this);
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Domain::parseActionSection()
|
||||||
|
{
|
||||||
|
auto &parser = m_context.parser;
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>(":");
|
||||||
|
parser.expect<std::string>("action");
|
||||||
|
|
||||||
|
Action::parseDeclaration(m_context, *this);
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Domain::checkConsistency()
|
||||||
|
{
|
||||||
|
// Verify that constants are unique
|
||||||
|
// Verify that all primitive types are unique
|
||||||
|
// Check for case-sensitivity issues
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
253
src/plasp/pddl/Expression.cpp
Normal file
253
src/plasp/pddl/Expression.cpp
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
#include <plasp/pddl/Expression.h>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/Domain.h>
|
||||||
|
#include <plasp/pddl/ExpressionContext.h>
|
||||||
|
#include <plasp/pddl/Identifier.h>
|
||||||
|
#include <plasp/pddl/IO.h>
|
||||||
|
#include <plasp/pddl/expressions/And.h>
|
||||||
|
#include <plasp/pddl/expressions/Imply.h>
|
||||||
|
#include <plasp/pddl/expressions/Not.h>
|
||||||
|
#include <plasp/pddl/expressions/Or.h>
|
||||||
|
#include <plasp/pddl/expressions/Predicate.h>
|
||||||
|
#include <plasp/pddl/expressions/PredicateDeclaration.h>
|
||||||
|
#include <plasp/pddl/expressions/Unsupported.h>
|
||||||
|
#include <plasp/utils/IO.h>
|
||||||
|
#include <plasp/utils/ParserException.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Expression
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ExpressionPointer parseEffectBodyExpression(Context &context, ExpressionContext &expressionContext);
|
||||||
|
ExpressionPointer parsePredicate(Context &context, ExpressionContext &expressionContext);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ExpressionPointer parsePreconditionExpression(Context &context,
|
||||||
|
ExpressionContext &expressionContext)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
ExpressionPointer expression;
|
||||||
|
|
||||||
|
if ((expression = expressions::And::parse(context, expressionContext, parsePreconditionExpression)))
|
||||||
|
return expression;
|
||||||
|
|
||||||
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
|
||||||
|
const auto expressionIdentifierPosition = parser.position();
|
||||||
|
|
||||||
|
if (parser.probeIdentifier("forall", isIdentifier)
|
||||||
|
|| parser.probeIdentifier("preference", isIdentifier))
|
||||||
|
{
|
||||||
|
// TODO: refactor
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
return expressions::Unsupported::parse(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
return parseExpression(context, expressionContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ExpressionPointer parseExpression(Context &context, ExpressionContext &expressionContext)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
ExpressionPointer expression;
|
||||||
|
|
||||||
|
if ((expression = expressions::And::parse(context, expressionContext, parseExpression))
|
||||||
|
|| (expression = expressions::Or::parse(context, expressionContext, parseExpression))
|
||||||
|
|| (expression = expressions::Not::parse(context, expressionContext, parseExpression))
|
||||||
|
|| (expression = expressions::Imply::parse(context, expressionContext, parseExpression))
|
||||||
|
|| (expression = expressions::Predicate::parse(context, expressionContext)))
|
||||||
|
{
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
|
||||||
|
const auto expressionIdentifierPosition = parser.position();
|
||||||
|
|
||||||
|
if (parser.probeIdentifier("exists", isIdentifier)
|
||||||
|
|| parser.probeIdentifier("forall", isIdentifier)
|
||||||
|
|| parser.probeIdentifier("-", isIdentifier)
|
||||||
|
|| parser.probeIdentifier("=", isIdentifier)
|
||||||
|
|| parser.probeIdentifier("*", isIdentifier)
|
||||||
|
|| parser.probeIdentifier("+", isIdentifier)
|
||||||
|
|| parser.probeIdentifier("-", isIdentifier)
|
||||||
|
|| parser.probeIdentifier("/", isIdentifier)
|
||||||
|
|| parser.probeIdentifier(">", isIdentifier)
|
||||||
|
|| parser.probeIdentifier("<", isIdentifier)
|
||||||
|
|| parser.probeIdentifier("=", isIdentifier)
|
||||||
|
|| parser.probeIdentifier(">=", isIdentifier)
|
||||||
|
|| parser.probeIdentifier("<=", isIdentifier))
|
||||||
|
{
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
return expressions::Unsupported::parse(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
throw utils::ParserException(context.parser, "expression type “" + expressionIdentifier + "” unknown or not allowed in this context");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ExpressionPointer parseEffectExpression(Context &context, ExpressionContext &expressionContext)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
ExpressionPointer expression;
|
||||||
|
|
||||||
|
if ((expression = expressions::And::parse(context, expressionContext, parseEffectExpression)))
|
||||||
|
return expression;
|
||||||
|
|
||||||
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
|
||||||
|
const auto expressionIdentifierPosition = parser.position();
|
||||||
|
|
||||||
|
if (parser.probeIdentifier("forall", isIdentifier)
|
||||||
|
|| parser.probeIdentifier("when", isIdentifier))
|
||||||
|
{
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
return expressions::Unsupported::parse(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
return parseEffectBodyExpression(context, expressionContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ExpressionPointer parseEffectBodyExpression(Context &context, ExpressionContext &expressionContext)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
ExpressionPointer expression;
|
||||||
|
|
||||||
|
if ((expression = expressions::Not::parse(context, expressionContext, parsePredicate))
|
||||||
|
|| (expression = expressions::Predicate::parse(context, expressionContext)))
|
||||||
|
{
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
|
||||||
|
const auto expressionIdentifierPosition = parser.position();
|
||||||
|
|
||||||
|
if (parser.probeIdentifier("=", isIdentifier)
|
||||||
|
|| parser.probeIdentifier("assign", isIdentifier)
|
||||||
|
|| parser.probeIdentifier("scale-up", isIdentifier)
|
||||||
|
|| parser.probeIdentifier("scale-down", isIdentifier)
|
||||||
|
|| parser.probeIdentifier("increase", isIdentifier)
|
||||||
|
|| parser.probeIdentifier("decrease", isIdentifier))
|
||||||
|
{
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
return expressions::Unsupported::parse(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
throw utils::ParserException(context.parser, "expression type “" + expressionIdentifier + "” unknown or not allowed in this context");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ExpressionPointer parsePredicate(Context &context, ExpressionContext &expressionContext)
|
||||||
|
{
|
||||||
|
ExpressionPointer expression;
|
||||||
|
|
||||||
|
if ((expression = expressions::Predicate::parse(context, expressionContext)))
|
||||||
|
return expression;
|
||||||
|
|
||||||
|
throw utils::ParserException(context.parser, "expected predicate");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ExpressionPointer parseLiteral(Context &context, ExpressionContext &expressionContext)
|
||||||
|
{
|
||||||
|
ExpressionPointer expression;
|
||||||
|
|
||||||
|
if ((expression = parseAtomicFormula(context, expressionContext))
|
||||||
|
|| (expression = expressions::Not::parse(context, expressionContext, parseAtomicFormula)))
|
||||||
|
{
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ExpressionPointer parseAtomicFormula(Context &context, ExpressionContext &expressionContext)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
ExpressionPointer expression;
|
||||||
|
|
||||||
|
if ((expression = expressions::Predicate::parse(context, expressionContext)))
|
||||||
|
return expression;
|
||||||
|
|
||||||
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
if (!parser.probe<std::string>("("))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const auto expressionIdentifierPosition = parser.position();
|
||||||
|
|
||||||
|
if (parser.probeIdentifier("=", isIdentifier))
|
||||||
|
{
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
return expressions::Unsupported::parse(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
56
src/plasp/pddl/ExpressionContext.cpp
Normal file
56
src/plasp/pddl/ExpressionContext.cpp
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#include <plasp/pddl/ExpressionContext.h>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Domain.h>
|
||||||
|
#include <plasp/pddl/Problem.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// ExpressionContext
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ExpressionContext::ExpressionContext(Domain &domain, expressions::Variables ¶meters)
|
||||||
|
: domain(domain),
|
||||||
|
problem(nullptr),
|
||||||
|
parameters(parameters)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ExpressionContext::ExpressionContext(Domain &domain, Problem *problem, expressions::Variables ¶meters)
|
||||||
|
: domain(domain),
|
||||||
|
problem{problem},
|
||||||
|
parameters(parameters)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool ExpressionContext::hasRequirement(Requirement::Type requirementType) const
|
||||||
|
{
|
||||||
|
if (problem != nullptr)
|
||||||
|
return problem->hasRequirement(requirementType);
|
||||||
|
|
||||||
|
return domain.hasRequirement(requirementType);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void ExpressionContext::checkRequirement(Requirement::Type requirementType) const
|
||||||
|
{
|
||||||
|
if (problem != nullptr)
|
||||||
|
problem->checkRequirement(requirementType);
|
||||||
|
else
|
||||||
|
domain.checkRequirement(requirementType);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
90
src/plasp/pddl/InitialState.cpp
Normal file
90
src/plasp/pddl/InitialState.cpp
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
#include <plasp/pddl/InitialState.h>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/ExpressionContext.h>
|
||||||
|
#include <plasp/pddl/Identifier.h>
|
||||||
|
#include <plasp/pddl/IO.h>
|
||||||
|
#include <plasp/pddl/Problem.h>
|
||||||
|
#include <plasp/pddl/expressions/At.h>
|
||||||
|
#include <plasp/pddl/expressions/Predicate.h>
|
||||||
|
#include <plasp/pddl/expressions/Unsupported.h>
|
||||||
|
#include <plasp/utils/ParserException.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// InitialState
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::unique_ptr<InitialState> InitialState::parseDeclaration(Context &context,
|
||||||
|
ExpressionContext &expressionContext)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
auto initialState = std::make_unique<InitialState>(InitialState());
|
||||||
|
|
||||||
|
const auto parseInitialStateElement =
|
||||||
|
[&]() -> ExpressionPointer
|
||||||
|
{
|
||||||
|
ExpressionPointer expression;
|
||||||
|
|
||||||
|
// TODO: do not allow negative initial state literals
|
||||||
|
if ((expression = parseLiteral(context, expressionContext))
|
||||||
|
|| (expression = expressions::At::parse(context, expressionContext, parseLiteral)))
|
||||||
|
{
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
|
||||||
|
const auto expressionIdentifierPosition = parser.position();
|
||||||
|
|
||||||
|
if (parser.probeIdentifier("=", isIdentifier))
|
||||||
|
{
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
return expressions::Unsupported::parse(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
throw utils::ParserException(parser, "expression type “" + expressionIdentifier + "” unknown or not allowed in this context");
|
||||||
|
};
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
while (parser.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
ExpressionPointer expression;
|
||||||
|
|
||||||
|
if ((expression = parseInitialStateElement()))
|
||||||
|
initialState->m_facts.emplace_back(std::move(expression));
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return initialState;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const Expressions &InitialState::facts() const
|
||||||
|
{
|
||||||
|
return m_facts;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
399
src/plasp/pddl/Problem.cpp
Normal file
399
src/plasp/pddl/Problem.cpp
Normal file
@@ -0,0 +1,399 @@
|
|||||||
|
#include <plasp/pddl/Problem.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Domain.h>
|
||||||
|
#include <plasp/pddl/ExpressionContext.h>
|
||||||
|
#include <plasp/pddl/Identifier.h>
|
||||||
|
#include <plasp/pddl/IO.h>
|
||||||
|
#include <plasp/pddl/expressions/Constant.h>
|
||||||
|
#include <plasp/utils/IO.h>
|
||||||
|
#include <plasp/utils/ParserException.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Problem
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Problem::Problem(Context &context, Domain &domain)
|
||||||
|
: m_context(context),
|
||||||
|
m_domain(domain),
|
||||||
|
m_domainPosition{-1},
|
||||||
|
m_requirementsPosition{-1},
|
||||||
|
m_objectsPosition{-1},
|
||||||
|
m_initialStatePosition{-1},
|
||||||
|
m_goalPosition{-1}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Problem::findSections()
|
||||||
|
{
|
||||||
|
auto &parser = m_context.parser;
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>("define");
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>("problem");
|
||||||
|
|
||||||
|
m_name = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
|
||||||
|
const auto setSectionPosition =
|
||||||
|
[&](const std::string §ionName, auto §ionPosition, const auto value, bool unique = false)
|
||||||
|
{
|
||||||
|
if (unique && sectionPosition != -1)
|
||||||
|
{
|
||||||
|
parser.seek(value);
|
||||||
|
throw utils::ParserException(parser, "only one “:" + sectionName + "” section allowed");
|
||||||
|
}
|
||||||
|
|
||||||
|
sectionPosition = value;
|
||||||
|
};
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
while (parser.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>(":");
|
||||||
|
|
||||||
|
const auto sectionIdentifierPosition = parser.position();
|
||||||
|
|
||||||
|
// TODO: check order of the sections
|
||||||
|
if (parser.probeIdentifier("domain", isIdentifier))
|
||||||
|
setSectionPosition("domain", m_domainPosition, position, true);
|
||||||
|
else if (parser.probeIdentifier("requirements", isIdentifier))
|
||||||
|
setSectionPosition("requirements", m_requirementsPosition, position, true);
|
||||||
|
else if (parser.probeIdentifier("objects", isIdentifier))
|
||||||
|
setSectionPosition("objects", m_objectsPosition, position, true);
|
||||||
|
else if (parser.probeIdentifier("init", isIdentifier))
|
||||||
|
setSectionPosition("init", m_initialStatePosition, position, true);
|
||||||
|
else if (parser.probeIdentifier("goal", isIdentifier))
|
||||||
|
setSectionPosition("goal", m_goalPosition, position, true);
|
||||||
|
else if (parser.probeIdentifier("constraints", isIdentifier)
|
||||||
|
|| parser.probeIdentifier("metric", isIdentifier)
|
||||||
|
|| parser.probeIdentifier("length", isIdentifier))
|
||||||
|
{
|
||||||
|
parser.seek(sectionIdentifierPosition);
|
||||||
|
|
||||||
|
const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
m_context.logger.logWarning(parser, "section type “" + sectionIdentifier + "” currently unsupported");
|
||||||
|
|
||||||
|
parser.seek(sectionIdentifierPosition);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
throw utils::ParserException(m_context.parser, "unknown problem section “" + sectionIdentifier + "”");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip section for now and parse it later
|
||||||
|
skipSection(parser);
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Problem::parse()
|
||||||
|
{
|
||||||
|
auto &parser = m_context.parser;
|
||||||
|
|
||||||
|
if (m_domainPosition == -1)
|
||||||
|
throw ConsistencyException("problem description does not specify the corresponding domain");
|
||||||
|
|
||||||
|
parser.seek(m_domainPosition);
|
||||||
|
parseDomainSection();
|
||||||
|
|
||||||
|
if (m_requirementsPosition != -1)
|
||||||
|
{
|
||||||
|
parser.seek(m_requirementsPosition);
|
||||||
|
parseRequirementSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_objectsPosition != -1)
|
||||||
|
{
|
||||||
|
parser.seek(m_objectsPosition);
|
||||||
|
parseObjectSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_initialStatePosition == -1)
|
||||||
|
throw ConsistencyException("problem description does not specify an initial state");
|
||||||
|
|
||||||
|
parser.seek(m_initialStatePosition);
|
||||||
|
parseInitialStateSection();
|
||||||
|
|
||||||
|
if (m_goalPosition == -1)
|
||||||
|
throw ConsistencyException("problem description does not specify a goal");
|
||||||
|
|
||||||
|
parser.seek(m_goalPosition);
|
||||||
|
parseGoalSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Domain &Problem::domain()
|
||||||
|
{
|
||||||
|
return m_domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const Domain &Problem::domain() const
|
||||||
|
{
|
||||||
|
return m_domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::string &Problem::name() const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const Requirements &Problem::requirements() const
|
||||||
|
{
|
||||||
|
return m_requirements;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
expressions::Constants &Problem::objects()
|
||||||
|
{
|
||||||
|
return m_objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const expressions::Constants &Problem::objects() const
|
||||||
|
{
|
||||||
|
return m_objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Problem::parseDomainSection()
|
||||||
|
{
|
||||||
|
auto &parser = m_context.parser;
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>(":");
|
||||||
|
parser.expect<std::string>("domain");
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
const auto domainName = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
if (m_domain.name() != domainName)
|
||||||
|
throw utils::ParserException(parser, "domains do not match (“" + m_domain.name() + "” and “" + domainName + "”)");
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Problem::parseRequirementSection()
|
||||||
|
{
|
||||||
|
auto &parser = m_context.parser;
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>(":");
|
||||||
|
parser.expect<std::string>("requirements");
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
while (parser.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
parser.expect<std::string>(":");
|
||||||
|
|
||||||
|
m_requirements.emplace_back(Requirement::parse(m_context));
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: do this check only once the domain is parsed
|
||||||
|
// If no requirements are specified, assume STRIPS
|
||||||
|
if (m_requirements.empty())
|
||||||
|
m_requirements.emplace_back(Requirement::Type::STRIPS);
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool Problem::hasRequirement(Requirement::Type requirementType) const
|
||||||
|
{
|
||||||
|
const auto match = std::find_if(m_requirements.cbegin(), m_requirements.cend(),
|
||||||
|
[&](const auto &requirement)
|
||||||
|
{
|
||||||
|
return requirement.type() == requirementType;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (match != m_requirements.cend())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return m_domain.hasRequirement(requirementType);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Problem::checkRequirement(Requirement::Type requirementType) const
|
||||||
|
{
|
||||||
|
if (hasRequirement(requirementType))
|
||||||
|
return;
|
||||||
|
|
||||||
|
throw ConsistencyException("requirement “" + Requirement(requirementType).toPDDL() + "” used but never declared");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Problem::computeDerivedRequirements()
|
||||||
|
{
|
||||||
|
const auto addRequirementUnique =
|
||||||
|
[&](const auto requirement)
|
||||||
|
{
|
||||||
|
if (hasRequirement(requirement))
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_requirements.push_back(Requirement(requirement));
|
||||||
|
};
|
||||||
|
|
||||||
|
if (hasRequirement(Requirement::Type::ADL))
|
||||||
|
{
|
||||||
|
addRequirementUnique(Requirement::Type::STRIPS);
|
||||||
|
addRequirementUnique(Requirement::Type::Typing);
|
||||||
|
addRequirementUnique(Requirement::Type::NegativePreconditions);
|
||||||
|
addRequirementUnique(Requirement::Type::DisjunctivePreconditions);
|
||||||
|
addRequirementUnique(Requirement::Type::Equality);
|
||||||
|
addRequirementUnique(Requirement::Type::QuantifiedPreconditions);
|
||||||
|
addRequirementUnique(Requirement::Type::ConditionalEffects);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasRequirement(Requirement::Type::QuantifiedPreconditions))
|
||||||
|
{
|
||||||
|
addRequirementUnique(Requirement::Type::ExistentialPreconditions);
|
||||||
|
addRequirementUnique(Requirement::Type::UniversalPreconditions);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasRequirement(Requirement::Type::Fluents))
|
||||||
|
{
|
||||||
|
addRequirementUnique(Requirement::Type::NumericFluents);
|
||||||
|
addRequirementUnique(Requirement::Type::ObjectFluents);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasRequirement(Requirement::Type::TimedInitialLiterals))
|
||||||
|
addRequirementUnique(Requirement::Type::DurativeActions);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Problem::parseObjectSection()
|
||||||
|
{
|
||||||
|
auto &parser = m_context.parser;
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>(":");
|
||||||
|
parser.expect<std::string>("objects");
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
// Store constants
|
||||||
|
expressions::Constant::parseTypedDeclarations(m_context, *this);
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Problem::parseInitialStateSection()
|
||||||
|
{
|
||||||
|
auto &parser = m_context.parser;
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>(":");
|
||||||
|
parser.expect<std::string>("init");
|
||||||
|
|
||||||
|
// TODO: remove workaround
|
||||||
|
expressions::Variables noParameters;
|
||||||
|
ExpressionContext expressionContext(m_domain, this, noParameters);
|
||||||
|
|
||||||
|
m_initialState = InitialState::parseDeclaration(m_context, expressionContext);
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Problem::parseGoalSection()
|
||||||
|
{
|
||||||
|
auto &parser = m_context.parser;
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>(":");
|
||||||
|
parser.expect<std::string>("goal");
|
||||||
|
|
||||||
|
// TODO: remove workaround
|
||||||
|
expressions::Variables noParameters;
|
||||||
|
ExpressionContext expressionContext(m_domain, this, noParameters);
|
||||||
|
|
||||||
|
m_goal = parsePreconditionExpression(m_context, expressionContext);
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
InitialState &Problem::initialState()
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(m_initialState);
|
||||||
|
|
||||||
|
return *m_initialState;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const InitialState &Problem::initialState() const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(m_initialState);
|
||||||
|
|
||||||
|
return *m_initialState;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const Expression &Problem::goal() const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(m_goal);
|
||||||
|
|
||||||
|
return *m_goal;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Problem::checkConsistency()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
134
src/plasp/pddl/Requirement.cpp
Normal file
134
src/plasp/pddl/Requirement.cpp
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
#include <plasp/pddl/Requirement.h>
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
#include <boost/assign.hpp>
|
||||||
|
#include <boost/bimap.hpp>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Identifier.h>
|
||||||
|
#include <plasp/utils/IO.h>
|
||||||
|
#include <plasp/utils/ParserException.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Requirement
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
using RequirementTypeNames = boost::bimap<Requirement::Type, std::string>;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const RequirementTypeNames requirementTypesToPDDL = boost::assign::list_of<RequirementTypeNames::relation>
|
||||||
|
(Requirement::Type::STRIPS, "strips")
|
||||||
|
(Requirement::Type::Typing, "typing")
|
||||||
|
(Requirement::Type::NegativePreconditions, "negative-preconditions")
|
||||||
|
(Requirement::Type::DisjunctivePreconditions, "disjunctive-preconditions")
|
||||||
|
(Requirement::Type::Equality, "equality")
|
||||||
|
(Requirement::Type::ExistentialPreconditions, "existential-preconditions")
|
||||||
|
(Requirement::Type::UniversalPreconditions, "universal-preconditions")
|
||||||
|
(Requirement::Type::QuantifiedPreconditions, "quantified-preconditions")
|
||||||
|
(Requirement::Type::ConditionalEffects, "conditional-effects")
|
||||||
|
(Requirement::Type::Fluents, "fluents")
|
||||||
|
(Requirement::Type::NumericFluents, "numeric-fluents")
|
||||||
|
(Requirement::Type::ObjectFluents, "object-fluents")
|
||||||
|
(Requirement::Type::ADL, "adl")
|
||||||
|
(Requirement::Type::DurativeActions, "durative-actions")
|
||||||
|
(Requirement::Type::DurationInequalities, "duration-inequalities")
|
||||||
|
(Requirement::Type::ContinuousEffects, "continuous-effects")
|
||||||
|
(Requirement::Type::DerivedPredicates, "derived-predicates")
|
||||||
|
(Requirement::Type::TimedInitialLiterals, "timed-initial-literals")
|
||||||
|
(Requirement::Type::Preferences, "preferences")
|
||||||
|
(Requirement::Type::Constraints, "constraints")
|
||||||
|
(Requirement::Type::ActionCosts, "action-costs")
|
||||||
|
(Requirement::Type::GoalUtilities, "goal-utilities");
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const RequirementTypeNames requirementTypesToASP = boost::assign::list_of<RequirementTypeNames::relation>
|
||||||
|
(Requirement::Type::STRIPS, "strips")
|
||||||
|
(Requirement::Type::Typing, "typing")
|
||||||
|
(Requirement::Type::NegativePreconditions, "negativePreconditions")
|
||||||
|
(Requirement::Type::DisjunctivePreconditions, "disjunctivePreconditions")
|
||||||
|
(Requirement::Type::Equality, "equality")
|
||||||
|
(Requirement::Type::ExistentialPreconditions, "existentialPreconditions")
|
||||||
|
(Requirement::Type::UniversalPreconditions, "universalPreconditions")
|
||||||
|
(Requirement::Type::QuantifiedPreconditions, "quantifiedPreconditions")
|
||||||
|
(Requirement::Type::ConditionalEffects, "conditionalEffects")
|
||||||
|
(Requirement::Type::Fluents, "fluents")
|
||||||
|
(Requirement::Type::NumericFluents, "numericFluents")
|
||||||
|
(Requirement::Type::ObjectFluents, "objectFluents")
|
||||||
|
(Requirement::Type::ADL, "adl")
|
||||||
|
(Requirement::Type::DurativeActions, "durativeActions")
|
||||||
|
(Requirement::Type::DurationInequalities, "durationInequalities")
|
||||||
|
(Requirement::Type::ContinuousEffects, "continuousEffects")
|
||||||
|
(Requirement::Type::DerivedPredicates, "derivedPredicates")
|
||||||
|
(Requirement::Type::TimedInitialLiterals, "timedInitialLiterals")
|
||||||
|
(Requirement::Type::Preferences, "preferences")
|
||||||
|
(Requirement::Type::Constraints, "constraints")
|
||||||
|
(Requirement::Type::ActionCosts, "actionCosts")
|
||||||
|
(Requirement::Type::GoalUtilities, "goalUtilities");
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Requirement::Requirement(Requirement::Type type)
|
||||||
|
: m_type{type}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Requirement Requirement::parse(Context &context)
|
||||||
|
{
|
||||||
|
const auto requirementName = context.parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
const auto match = requirementTypesToPDDL.right.find(requirementName);
|
||||||
|
|
||||||
|
if (match == requirementTypesToPDDL.right.end())
|
||||||
|
throw utils::ParserException(context.parser, "unknown PDDL requirement “" + requirementName + "”");
|
||||||
|
|
||||||
|
const auto requirementType = match->second;
|
||||||
|
|
||||||
|
if (requirementType == Requirement::Type::GoalUtilities)
|
||||||
|
context.logger.logWarning(context.parser, "requirement “goal-utilities” is not part of the PDDL 3.1 specification");
|
||||||
|
|
||||||
|
return Requirement(match->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Requirement::Type Requirement::type() const
|
||||||
|
{
|
||||||
|
return m_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::string Requirement::toPDDL() const
|
||||||
|
{
|
||||||
|
const auto match = requirementTypesToPDDL.left.find(m_type);
|
||||||
|
|
||||||
|
BOOST_ASSERT(match != requirementTypesToPDDL.left.end());
|
||||||
|
|
||||||
|
return match->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::string Requirement::toASP() const
|
||||||
|
{
|
||||||
|
const auto match = requirementTypesToASP.left.find(m_type);
|
||||||
|
|
||||||
|
BOOST_ASSERT(match != requirementTypesToASP.left.end());
|
||||||
|
|
||||||
|
return match->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
505
src/plasp/pddl/TranslatorASP.cpp
Normal file
505
src/plasp/pddl/TranslatorASP.cpp
Normal file
@@ -0,0 +1,505 @@
|
|||||||
|
#include <plasp/pddl/TranslatorASP.h>
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
|
#include <plasp/pddl/expressions/And.h>
|
||||||
|
#include <plasp/pddl/expressions/Not.h>
|
||||||
|
#include <plasp/pddl/expressions/Predicate.h>
|
||||||
|
#include <plasp/utils/Formatting.h>
|
||||||
|
#include <plasp/utils/IO.h>
|
||||||
|
#include <plasp/utils/TranslatorException.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// TranslatorASP
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
TranslatorASP::TranslatorASP(const Description &description, utils::LogStream &outputStream)
|
||||||
|
: m_description(description),
|
||||||
|
m_outputStream(outputStream)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TranslatorASP::translate() const
|
||||||
|
{
|
||||||
|
translateDomain();
|
||||||
|
|
||||||
|
if (m_description.containsProblem())
|
||||||
|
{
|
||||||
|
m_outputStream << std::endl;
|
||||||
|
translateProblem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TranslatorASP::translateDomain() const
|
||||||
|
{
|
||||||
|
m_outputStream << utils::Heading1("domain");
|
||||||
|
|
||||||
|
const auto &domain = m_description.domain();
|
||||||
|
|
||||||
|
// Types
|
||||||
|
m_outputStream << std::endl;
|
||||||
|
translateTypes();
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
if (!domain.constants().empty())
|
||||||
|
{
|
||||||
|
m_outputStream << std::endl;
|
||||||
|
translateConstants("constants", domain.constants());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Predicates
|
||||||
|
if (!domain.predicates().empty())
|
||||||
|
{
|
||||||
|
m_outputStream << std::endl;
|
||||||
|
translatePredicates();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
if (!domain.actions().empty())
|
||||||
|
{
|
||||||
|
m_outputStream << std::endl;
|
||||||
|
translateActions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TranslatorASP::translateTypes() const
|
||||||
|
{
|
||||||
|
m_outputStream << utils::Heading2("types");
|
||||||
|
|
||||||
|
m_outputStream << std::endl;
|
||||||
|
|
||||||
|
const auto &types = m_description.domain().types();
|
||||||
|
|
||||||
|
if (types.empty())
|
||||||
|
{
|
||||||
|
m_outputStream << utils::Keyword("type") << "(object)." << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::for_each(types.cbegin(), types.cend(),
|
||||||
|
[&](const auto &type)
|
||||||
|
{
|
||||||
|
const auto typeName = utils::escapeASP(type->name());
|
||||||
|
|
||||||
|
m_outputStream << utils::Keyword("type") << "(" << typeName << ")." << std::endl;
|
||||||
|
|
||||||
|
const auto &parentTypes = type->parentTypes();
|
||||||
|
|
||||||
|
std::for_each(parentTypes.cbegin(), parentTypes.cend(),
|
||||||
|
[&](const auto &parentType)
|
||||||
|
{
|
||||||
|
const auto parentTypeName = utils::escapeASP(parentType->name());
|
||||||
|
|
||||||
|
m_outputStream
|
||||||
|
<< utils::Keyword("inherits") << "(" << utils::Keyword("type")
|
||||||
|
<< "(" << typeName << "), " << utils::Keyword("type")
|
||||||
|
<< "(" << parentTypeName << "))." << std::endl
|
||||||
|
|
||||||
|
<< utils::Keyword("hasType") << "(" << utils::Variable("X") << ", "
|
||||||
|
<< utils::Keyword("type") << "(" << parentTypeName << ")) :- "
|
||||||
|
<< utils::Keyword("hasType") << "(" << utils::Variable("X") << ", "
|
||||||
|
<< utils::Keyword("type") << "(" << typeName << "))." << std::endl;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TranslatorASP::translatePredicates() const
|
||||||
|
{
|
||||||
|
m_outputStream << utils::Heading2("predicates");
|
||||||
|
|
||||||
|
const auto &predicates = m_description.domain().predicates();
|
||||||
|
|
||||||
|
std::for_each(predicates.cbegin(), predicates.cend(),
|
||||||
|
[&](const auto &predicate)
|
||||||
|
{
|
||||||
|
m_outputStream << std::endl;
|
||||||
|
|
||||||
|
m_outputStream << utils::Keyword("predicate") << "(" << utils::escapeASP(predicate->name());
|
||||||
|
|
||||||
|
this->translateVariablesHead(predicate->arguments());
|
||||||
|
|
||||||
|
m_outputStream << ")";
|
||||||
|
|
||||||
|
this->translateVariablesBody(predicate->arguments());
|
||||||
|
|
||||||
|
m_outputStream << ".";
|
||||||
|
});
|
||||||
|
|
||||||
|
m_outputStream << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TranslatorASP::translateActions() const
|
||||||
|
{
|
||||||
|
m_outputStream << utils::Heading2("actions");
|
||||||
|
|
||||||
|
const auto &actions = m_description.domain().actions();
|
||||||
|
|
||||||
|
const auto printActionName =
|
||||||
|
[&](const auto &action)
|
||||||
|
{
|
||||||
|
m_outputStream << utils::Keyword("action") << "(" << utils::escapeASP(action.name());
|
||||||
|
|
||||||
|
this->translateVariablesHead(action.parameters());
|
||||||
|
|
||||||
|
m_outputStream << ")";
|
||||||
|
};
|
||||||
|
|
||||||
|
std::for_each(actions.cbegin(), actions.cend(),
|
||||||
|
[&](const auto &action)
|
||||||
|
{
|
||||||
|
const auto translateLiteral =
|
||||||
|
[&](const auto &ruleHead, const auto &literal)
|
||||||
|
{
|
||||||
|
m_outputStream << std::endl << utils::Keyword(ruleHead) << "(";
|
||||||
|
|
||||||
|
printActionName(*action);
|
||||||
|
|
||||||
|
m_outputStream << ", ";
|
||||||
|
|
||||||
|
this->translateLiteral(literal);
|
||||||
|
|
||||||
|
m_outputStream << ") :- ";
|
||||||
|
|
||||||
|
printActionName(*action);
|
||||||
|
|
||||||
|
m_outputStream << ".";
|
||||||
|
};
|
||||||
|
|
||||||
|
m_outputStream << std::endl;
|
||||||
|
|
||||||
|
// Name
|
||||||
|
printActionName(*action);
|
||||||
|
|
||||||
|
this->translateVariablesBody(action->parameters());
|
||||||
|
|
||||||
|
m_outputStream << ".";
|
||||||
|
|
||||||
|
// Precondition
|
||||||
|
if (action->precondition())
|
||||||
|
{
|
||||||
|
const auto &precondition = *action->precondition();
|
||||||
|
|
||||||
|
if (precondition.expressionType() == Expression::Type::Predicate
|
||||||
|
|| precondition.expressionType() == Expression::Type::Not)
|
||||||
|
{
|
||||||
|
translateLiteral("precondition", precondition);
|
||||||
|
}
|
||||||
|
// Assuming a conjunction
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (precondition.expressionType() != Expression::Type::And)
|
||||||
|
throw utils::TranslatorException("only “and” expressions and (negated) predicates supported as action preconditions currently");
|
||||||
|
|
||||||
|
const auto &andExpression = dynamic_cast<const expressions::And &>(precondition);
|
||||||
|
|
||||||
|
std::for_each(andExpression.arguments().cbegin(), andExpression.arguments().cend(),
|
||||||
|
[&](const auto *argument)
|
||||||
|
{
|
||||||
|
translateLiteral("precondition", *argument);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Effect
|
||||||
|
if (action->effect())
|
||||||
|
{
|
||||||
|
const auto &effect = *action->effect();
|
||||||
|
|
||||||
|
if (effect.expressionType() == Expression::Type::Predicate
|
||||||
|
|| effect.expressionType() == Expression::Type::Not)
|
||||||
|
{
|
||||||
|
translateLiteral("postcondition", effect);
|
||||||
|
}
|
||||||
|
// Assuming a conjunction
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (effect.expressionType() != Expression::Type::And)
|
||||||
|
throw utils::TranslatorException("only “and” expressions and (negated) predicates supported as action effects currently");
|
||||||
|
|
||||||
|
const auto &andExpression = dynamic_cast<const expressions::And &>(effect);
|
||||||
|
|
||||||
|
std::for_each(andExpression.arguments().cbegin(), andExpression.arguments().cend(),
|
||||||
|
[&](const auto *argument)
|
||||||
|
{
|
||||||
|
translateLiteral("postcondition", *argument);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_outputStream << std::endl;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TranslatorASP::translateConstants(const std::string &heading, const expressions::Constants &constants) const
|
||||||
|
{
|
||||||
|
m_outputStream << utils::Heading2(heading);
|
||||||
|
|
||||||
|
std::for_each(constants.cbegin(), constants.cend(),
|
||||||
|
[&](const auto &constant)
|
||||||
|
{
|
||||||
|
const auto constantName = utils::escapeASP(constant->name());
|
||||||
|
|
||||||
|
m_outputStream << std::endl << utils::Keyword("constant")
|
||||||
|
<< "(" << constantName << ")." << std::endl;
|
||||||
|
|
||||||
|
const auto *type = constant->type();
|
||||||
|
|
||||||
|
if (type != nullptr)
|
||||||
|
{
|
||||||
|
m_outputStream << utils::Keyword("hasType") << "("
|
||||||
|
<< utils::Keyword("constant") << "(" << constantName << "), "
|
||||||
|
<< utils::Keyword("type") << "(" << utils::escapeASP(type->name()) << "))." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_outputStream << utils::Keyword("hasType") << "("
|
||||||
|
<< utils::Keyword("constant") << "(" << constantName << "), "
|
||||||
|
<< utils::Keyword("type") << "(object))." << std::endl;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TranslatorASP::translateVariablesHead(const expressions::Variables &variables) const
|
||||||
|
{
|
||||||
|
if (variables.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_outputStream << "(";
|
||||||
|
|
||||||
|
for (auto i = variables.cbegin(); i != variables.cend(); i++)
|
||||||
|
{
|
||||||
|
if (i != variables.cbegin())
|
||||||
|
m_outputStream << ", ";
|
||||||
|
|
||||||
|
const auto &variable = **i;
|
||||||
|
|
||||||
|
m_outputStream << utils::Variable(utils::escapeASPVariable(variable.name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_outputStream << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TranslatorASP::translateVariablesBody(const expressions::Variables &variables) const
|
||||||
|
{
|
||||||
|
if (variables.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_outputStream << " :- ";
|
||||||
|
|
||||||
|
for (auto i = variables.cbegin(); i != variables.cend(); i++)
|
||||||
|
{
|
||||||
|
const auto &variable = **i;
|
||||||
|
|
||||||
|
if (i != variables.cbegin())
|
||||||
|
m_outputStream << ", ";
|
||||||
|
|
||||||
|
if (variable.type() != nullptr)
|
||||||
|
{
|
||||||
|
if (variable.type()->expressionType() != Expression::Type::PrimitiveType)
|
||||||
|
throw utils::TranslatorException("only primitive types supported currently");
|
||||||
|
|
||||||
|
const auto &type = *dynamic_cast<const expressions::PrimitiveType *>(variable.type());
|
||||||
|
|
||||||
|
m_outputStream << utils::Keyword("hasType") << "("
|
||||||
|
<< utils::Variable(utils::escapeASPVariable(variable.name())) << ", "
|
||||||
|
<< utils::Keyword("type") << "(" << utils::escapeASP(type.name()) << "))";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_outputStream << utils::Keyword("hasType") << "("
|
||||||
|
<< utils::Variable(utils::escapeASPVariable(variable.name())) << ", "
|
||||||
|
<< utils::Keyword("type") << "(object))";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TranslatorASP::translateLiteral(const Expression &literal) const
|
||||||
|
{
|
||||||
|
// Translate single predicate
|
||||||
|
if (literal.expressionType() == Expression::Type::Predicate)
|
||||||
|
{
|
||||||
|
this->translatePredicate(dynamic_cast<const expressions::Predicate &>(literal));
|
||||||
|
m_outputStream << ", " << utils::Keyword("true");
|
||||||
|
}
|
||||||
|
// Assuming that "not" expression may only contain a predicate
|
||||||
|
else if (literal.expressionType() == Expression::Type::Not)
|
||||||
|
{
|
||||||
|
const auto ¬Expression = dynamic_cast<const expressions::Not &>(literal);
|
||||||
|
const auto &predicate = dynamic_cast<const expressions::Predicate &>(*notExpression.argument());
|
||||||
|
|
||||||
|
this->translatePredicate(predicate);
|
||||||
|
m_outputStream << ", " << utils::Keyword("false");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw utils::TranslatorException("only primitive predicates and their negations supported as literals currently");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TranslatorASP::translatePredicate(const expressions::Predicate &predicate) const
|
||||||
|
{
|
||||||
|
m_outputStream << utils::Keyword("predicate") << "(" << utils::escapeASP(predicate.name());
|
||||||
|
|
||||||
|
const auto &arguments = predicate.arguments();
|
||||||
|
|
||||||
|
if (arguments.empty())
|
||||||
|
{
|
||||||
|
m_outputStream << ")";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_outputStream << "(";
|
||||||
|
|
||||||
|
for (auto i = arguments.cbegin(); i != arguments.cend(); i++)
|
||||||
|
{
|
||||||
|
if (i != arguments.cbegin())
|
||||||
|
m_outputStream << ", ";
|
||||||
|
|
||||||
|
if ((*i)->expressionType() == Expression::Type::Constant)
|
||||||
|
{
|
||||||
|
const auto &constant = dynamic_cast<const expressions::Constant &>(**i);
|
||||||
|
|
||||||
|
m_outputStream << utils::Keyword("constant") << "(" << utils::escapeASP(constant.name()) << ")";
|
||||||
|
}
|
||||||
|
else if ((*i)->expressionType() == Expression::Type::Variable)
|
||||||
|
{
|
||||||
|
const auto &variable = dynamic_cast<const expressions::Variable &>(**i);
|
||||||
|
|
||||||
|
m_outputStream << utils::Variable(utils::escapeASPVariable(variable.name()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw utils::TranslatorException("only variables and constants supported in predicates currently");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_outputStream << "))";
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TranslatorASP::translateProblem() const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(m_description.containsProblem());
|
||||||
|
|
||||||
|
m_outputStream << utils::Heading1("problem");
|
||||||
|
|
||||||
|
const auto &problem = m_description.problem();
|
||||||
|
|
||||||
|
// Objects
|
||||||
|
if (!problem.objects().empty())
|
||||||
|
{
|
||||||
|
m_outputStream << std::endl;
|
||||||
|
translateConstants("objects", problem.objects());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initial State
|
||||||
|
m_outputStream << std::endl;
|
||||||
|
translateInitialState();
|
||||||
|
|
||||||
|
// Goal
|
||||||
|
m_outputStream << std::endl;
|
||||||
|
translateGoal();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TranslatorASP::translateInitialState() const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(m_description.containsProblem());
|
||||||
|
|
||||||
|
m_outputStream << utils::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::Keyword("initialState") << "(";
|
||||||
|
|
||||||
|
// Translate single predicate
|
||||||
|
if (fact->expressionType() == Expression::Type::Predicate)
|
||||||
|
this->translatePredicate(dynamic_cast<const expressions::Predicate &>(*fact));
|
||||||
|
// Assuming that "not" expression may only contain a predicate
|
||||||
|
else if (fact->expressionType() == Expression::Type::Not)
|
||||||
|
{
|
||||||
|
const auto ¬Expression = dynamic_cast<const expressions::Not &>(*fact);
|
||||||
|
|
||||||
|
if (notExpression.argument()->expressionType() != Expression::Type::Predicate)
|
||||||
|
throw utils::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");
|
||||||
|
|
||||||
|
m_outputStream << ").";
|
||||||
|
});
|
||||||
|
|
||||||
|
m_outputStream << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TranslatorASP::translateGoal() const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(m_description.containsProblem());
|
||||||
|
|
||||||
|
m_outputStream << utils::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::Keyword("goal") << "(";
|
||||||
|
|
||||||
|
translateLiteral(goal);
|
||||||
|
|
||||||
|
m_outputStream << ").";
|
||||||
|
}
|
||||||
|
else if (goal.expressionType() == Expression::Type::And)
|
||||||
|
{
|
||||||
|
const auto &andExpression = dynamic_cast<const expressions::And &>(goal);
|
||||||
|
|
||||||
|
std::for_each(andExpression.arguments().cbegin(), andExpression.arguments().cend(),
|
||||||
|
[&](const auto *argument)
|
||||||
|
{
|
||||||
|
m_outputStream << std::endl << utils::Keyword("goal") << "(";
|
||||||
|
|
||||||
|
this->translateLiteral(*argument);
|
||||||
|
|
||||||
|
m_outputStream << ").";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw utils::TranslatorException("only single predicates, their negations, and conjunctions are currently supported in the goal");
|
||||||
|
|
||||||
|
m_outputStream << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
22
src/plasp/pddl/expressions/And.cpp
Normal file
22
src/plasp/pddl/expressions/And.cpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#include <plasp/pddl/expressions/And.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// And
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::string And::Identifier = "and";
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
48
src/plasp/pddl/expressions/At.cpp
Normal file
48
src/plasp/pddl/expressions/At.cpp
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
#include <plasp/pddl/expressions/At.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// At
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
At::At()
|
||||||
|
: m_argument{nullptr}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void At::setArgument(const Expression *argument)
|
||||||
|
{
|
||||||
|
m_argumentStorage = nullptr;
|
||||||
|
m_argument = argument;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void At::setArgument(ExpressionPointer &&argument)
|
||||||
|
{
|
||||||
|
m_argumentStorage = std::move(argument);
|
||||||
|
m_argument = m_argumentStorage.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const Expression *At::argument() const
|
||||||
|
{
|
||||||
|
return m_argument;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
240
src/plasp/pddl/expressions/Constant.cpp
Normal file
240
src/plasp/pddl/expressions/Constant.cpp
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
#include <plasp/pddl/expressions/Constant.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/Domain.h>
|
||||||
|
#include <plasp/pddl/ExpressionContext.h>
|
||||||
|
#include <plasp/pddl/Problem.h>
|
||||||
|
#include <plasp/pddl/expressions/PrimitiveType.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Constant
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Constant::Constant()
|
||||||
|
: m_isDirty{false},
|
||||||
|
m_type{nullptr}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ConstantPointer Constant::parseDeclaration(Context &context)
|
||||||
|
{
|
||||||
|
context.parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
auto constant = std::make_unique<Constant>(Constant());
|
||||||
|
|
||||||
|
constant->m_name = context.parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
BOOST_ASSERT(constant->m_name != "-");
|
||||||
|
|
||||||
|
// Flag constant for potentially upcoming type declaration
|
||||||
|
constant->setDirty();
|
||||||
|
|
||||||
|
return constant;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Constant::parseTypedDeclaration(Context &context, Domain &domain)
|
||||||
|
{
|
||||||
|
parseTypedDeclaration(context, domain, domain.constants());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Constant::parseTypedDeclaration(Context &context, Problem &problem)
|
||||||
|
{
|
||||||
|
parseTypedDeclaration(context, problem.domain(), problem.objects());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Constant::parseTypedDeclaration(Context &context, Domain &domain, Constants &constants)
|
||||||
|
{
|
||||||
|
// Parse and store constant
|
||||||
|
constants.emplace_back(parseDeclaration(context));
|
||||||
|
|
||||||
|
context.parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
// Check for typing information
|
||||||
|
if (!context.parser.probe('-'))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If existing, parse and store parent type
|
||||||
|
auto *type = PrimitiveType::parseAndFind(context, domain);
|
||||||
|
|
||||||
|
// Assign parent type to all types that were previously flagged
|
||||||
|
std::for_each(constants.begin(), constants.end(),
|
||||||
|
[&](auto &constant)
|
||||||
|
{
|
||||||
|
if (!constant->isDirty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
constant->setType(type);
|
||||||
|
constant->setDirty(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Constant::parseTypedDeclarations(Context &context, Domain &domain)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
while (parser.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
parseTypedDeclaration(context, domain);
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (domain.constants().empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check correct use of typing requirement
|
||||||
|
const auto typingUsed = (domain.constants().back()->type() != nullptr);
|
||||||
|
|
||||||
|
// If types are given, check that typing is a requirement
|
||||||
|
if (typingUsed)
|
||||||
|
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, "constant has undeclared type");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Constant::parseTypedDeclarations(Context &context, Problem &problem)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
while (context.parser.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
parseTypedDeclaration(context, problem);
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (problem.objects().empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check correct use of typing requirement
|
||||||
|
const auto typingUsed = (problem.objects().back()->type() != nullptr);
|
||||||
|
|
||||||
|
// If types are given, check that typing is a requirement
|
||||||
|
if (typingUsed)
|
||||||
|
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(context.parser, "constant has undeclared type");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Constant *Constant::parseAndFind(Context &context, const Domain &domain)
|
||||||
|
{
|
||||||
|
context.parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
const auto constantName = context.parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
auto *constant = parseAndFind(constantName, domain.constants());
|
||||||
|
|
||||||
|
if (constant != nullptr)
|
||||||
|
return constant;
|
||||||
|
|
||||||
|
throw utils::ParserException(context.parser, "constant “" + constantName + "” used but never declared");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Constant *Constant::parseAndFind(Context &context, const Problem &problem)
|
||||||
|
{
|
||||||
|
context.parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
const auto constantName = context.parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
auto *constant = parseAndFind(constantName, problem.domain().constants());
|
||||||
|
|
||||||
|
if (constant)
|
||||||
|
return constant;
|
||||||
|
|
||||||
|
constant = parseAndFind(constantName, problem.objects());
|
||||||
|
|
||||||
|
if (constant)
|
||||||
|
return constant;
|
||||||
|
|
||||||
|
throw utils::ParserException(context.parser, "constant “" + constantName + "” used but never declared");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Constant *Constant::parseAndFind(const std::string &constantName, const Constants &constants)
|
||||||
|
{
|
||||||
|
const auto match = std::find_if(constants.cbegin(), constants.cend(),
|
||||||
|
[&](const auto &constant)
|
||||||
|
{
|
||||||
|
return constant->name() == constantName;
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto constantExists = (match != constants.cend());
|
||||||
|
|
||||||
|
if (!constantExists)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return match->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Constant::setDirty(bool isDirty)
|
||||||
|
{
|
||||||
|
m_isDirty = isDirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool Constant::isDirty() const
|
||||||
|
{
|
||||||
|
return m_isDirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::string &Constant::name() const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Constant::setType(const PrimitiveType *type)
|
||||||
|
{
|
||||||
|
m_type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const PrimitiveType *Constant::type() const
|
||||||
|
{
|
||||||
|
return m_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
src/plasp/pddl/expressions/Either.cpp
Normal file
22
src/plasp/pddl/expressions/Either.cpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#include <plasp/pddl/expressions/Either.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Either
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::string Either::Identifier = "either";
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
src/plasp/pddl/expressions/Imply.cpp
Normal file
22
src/plasp/pddl/expressions/Imply.cpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#include <plasp/pddl/expressions/Imply.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Imply
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::string Imply::Identifier = "imply";
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
48
src/plasp/pddl/expressions/Not.cpp
Normal file
48
src/plasp/pddl/expressions/Not.cpp
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
#include <plasp/pddl/expressions/Not.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Not
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Not::Not()
|
||||||
|
: m_argument{nullptr}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Not::setArgument(const Expression *argument)
|
||||||
|
{
|
||||||
|
m_argumentStorage = nullptr;
|
||||||
|
m_argument = argument;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Not::setArgument(ExpressionPointer &&argument)
|
||||||
|
{
|
||||||
|
m_argumentStorage = std::move(argument);
|
||||||
|
m_argument = m_argumentStorage.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const Expression *Not::argument() const
|
||||||
|
{
|
||||||
|
return m_argument;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
src/plasp/pddl/expressions/Or.cpp
Normal file
22
src/plasp/pddl/expressions/Or.cpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#include <plasp/pddl/expressions/Or.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Or
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::string Or::Identifier = "or";
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
176
src/plasp/pddl/expressions/Predicate.cpp
Normal file
176
src/plasp/pddl/expressions/Predicate.cpp
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
#include <plasp/pddl/expressions/Predicate.h>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/Domain.h>
|
||||||
|
#include <plasp/pddl/ExpressionContext.h>
|
||||||
|
#include <plasp/pddl/Identifier.h>
|
||||||
|
#include <plasp/pddl/Problem.h>
|
||||||
|
#include <plasp/pddl/expressions/Constant.h>
|
||||||
|
#include <plasp/pddl/expressions/Variable.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Predicate
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Predicate::Predicate()
|
||||||
|
: m_isDeclared{false}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
PredicatePointer Predicate::parse(Context &context, ExpressionContext &expressionContext)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
if (!parser.probe<std::string>("("))
|
||||||
|
{
|
||||||
|
parser.seek(position);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto predicateName = parser.parseIdentifier(isIdentifier);
|
||||||
|
const auto &predicates = expressionContext.domain.predicates();
|
||||||
|
|
||||||
|
const auto matchingPredicate = std::find_if(predicates.cbegin(), predicates.cend(),
|
||||||
|
[&](const auto &predicate)
|
||||||
|
{
|
||||||
|
return predicate->name() == predicateName;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (matchingPredicate == predicates.cend())
|
||||||
|
{
|
||||||
|
parser.seek(position);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto predicate = std::make_unique<Predicate>(Predicate());
|
||||||
|
|
||||||
|
predicate->m_name = predicateName;
|
||||||
|
|
||||||
|
context.parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
// Parse arguments
|
||||||
|
while (context.parser.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
// Parse variables
|
||||||
|
if (context.parser.currentCharacter() == '?')
|
||||||
|
{
|
||||||
|
const auto *variable = Variable::parseAndFind(context, expressionContext);
|
||||||
|
predicate->m_arguments.emplace_back(variable);
|
||||||
|
}
|
||||||
|
// Parse constants
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto *constant = (expressionContext.problem == nullptr)
|
||||||
|
? Constant::parseAndFind(context, expressionContext.domain)
|
||||||
|
: Constant::parseAndFind(context, *expressionContext.problem);
|
||||||
|
predicate->m_arguments.emplace_back(constant);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.parser.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: check that signature matches one of the declared ones
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
|
||||||
|
return predicate;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
PredicatePointer Predicate::parse(Context &context, const Problem &problem)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
if (!parser.probe<std::string>("("))
|
||||||
|
{
|
||||||
|
parser.seek(position);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto predicateName = parser.parseIdentifier(isIdentifier);
|
||||||
|
const auto &predicates = problem.domain().predicates();
|
||||||
|
|
||||||
|
const auto matchingPredicate = std::find_if(predicates.cbegin(), predicates.cend(),
|
||||||
|
[&](const auto &predicate)
|
||||||
|
{
|
||||||
|
return predicate->name() == predicateName;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (matchingPredicate == predicates.cend())
|
||||||
|
{
|
||||||
|
parser.seek(position);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto predicate = std::make_unique<Predicate>(Predicate());
|
||||||
|
|
||||||
|
predicate->m_name = predicateName;
|
||||||
|
|
||||||
|
context.parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
while (context.parser.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
if (context.parser.currentCharacter() == '?')
|
||||||
|
throw utils::ParserException(context.parser, "variables not allowed in this context");
|
||||||
|
|
||||||
|
// Parse objects and constants
|
||||||
|
const auto *constant = Constant::parseAndFind(context, problem);
|
||||||
|
predicate->m_arguments.emplace_back(constant);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: check that signature matches one of the declared ones
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
|
||||||
|
return predicate;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Predicate::setDeclared()
|
||||||
|
{
|
||||||
|
m_isDeclared = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool Predicate::isDeclared() const
|
||||||
|
{
|
||||||
|
return m_isDeclared;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::string &Predicate::name() const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::vector<const Expression *> &Predicate::arguments() const
|
||||||
|
{
|
||||||
|
return m_arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
85
src/plasp/pddl/expressions/PredicateDeclaration.cpp
Normal file
85
src/plasp/pddl/expressions/PredicateDeclaration.cpp
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
#include <plasp/pddl/expressions/PredicateDeclaration.h>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/Domain.h>
|
||||||
|
#include <plasp/pddl/ExpressionContext.h>
|
||||||
|
#include <plasp/pddl/Identifier.h>
|
||||||
|
#include <plasp/pddl/expressions/Constant.h>
|
||||||
|
#include <plasp/pddl/expressions/Variable.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PredicateDeclaration
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
PredicateDeclaration::PredicateDeclaration()
|
||||||
|
: m_isDeclared{false}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void PredicateDeclaration::parse(Context &context, Domain &domain)
|
||||||
|
{
|
||||||
|
context.parser.expect<std::string>("(");
|
||||||
|
|
||||||
|
auto predicate = std::make_unique<PredicateDeclaration>(PredicateDeclaration());
|
||||||
|
|
||||||
|
predicate->m_name = context.parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
// Flag predicate as correctly declared in the types section
|
||||||
|
predicate->setDeclared();
|
||||||
|
|
||||||
|
context.parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
ExpressionContext expressionContext(domain, predicate->m_parameters);
|
||||||
|
|
||||||
|
// Parse arguments
|
||||||
|
expressions::Variable::parseTypedDeclarations(context, expressionContext);
|
||||||
|
|
||||||
|
context.parser.expect<std::string>(")");
|
||||||
|
|
||||||
|
domain.predicates().emplace_back(std::move(predicate));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void PredicateDeclaration::setDeclared()
|
||||||
|
{
|
||||||
|
m_isDeclared = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool PredicateDeclaration::isDeclared() const
|
||||||
|
{
|
||||||
|
return m_isDeclared;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::string &PredicateDeclaration::name() const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const Variables &PredicateDeclaration::arguments() const
|
||||||
|
{
|
||||||
|
return m_parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
172
src/plasp/pddl/expressions/PrimitiveType.cpp
Normal file
172
src/plasp/pddl/expressions/PrimitiveType.cpp
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
#include <plasp/pddl/expressions/PrimitiveType.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/Domain.h>
|
||||||
|
#include <plasp/pddl/ExpressionContext.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PrimitiveType
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
PrimitiveType::PrimitiveType()
|
||||||
|
: m_isDirty{true}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
PrimitiveType::PrimitiveType(std::string name)
|
||||||
|
: m_isDirty{true},
|
||||||
|
m_name{name}
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(!m_name.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void PrimitiveType::parseDeclaration(Context &context, Domain &domain)
|
||||||
|
{
|
||||||
|
auto &types = domain.types();
|
||||||
|
|
||||||
|
context.parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
const auto typeName = context.parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
const auto match = std::find_if(types.cbegin(), types.cend(),
|
||||||
|
[&](const auto &primitiveType)
|
||||||
|
{
|
||||||
|
return primitiveType->name() == typeName;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Return existing primitive type
|
||||||
|
if (match != types.cend())
|
||||||
|
{
|
||||||
|
auto *type = match->get();
|
||||||
|
|
||||||
|
type->setDirty();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
types.emplace_back(std::make_unique<PrimitiveType>(typeName));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void PrimitiveType::parseTypedDeclaration(Context &context, Domain &domain)
|
||||||
|
{
|
||||||
|
auto &types = domain.types();
|
||||||
|
|
||||||
|
// Parse and store type
|
||||||
|
parseDeclaration(context, domain);
|
||||||
|
|
||||||
|
context.parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
// Check for type inheritance
|
||||||
|
if (!context.parser.probe('-'))
|
||||||
|
return;
|
||||||
|
|
||||||
|
domain.checkRequirement(Requirement::Type::Typing);
|
||||||
|
|
||||||
|
// If existing, parse and store parent type
|
||||||
|
auto *parentType = parseAndFind(context, domain);
|
||||||
|
|
||||||
|
parentType->setDirty(false);
|
||||||
|
|
||||||
|
// Assign parent type to all types that were previously flagged
|
||||||
|
std::for_each(types.begin(), types.end(),
|
||||||
|
[&](auto &childType)
|
||||||
|
{
|
||||||
|
if (!childType->isDirty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
childType->m_parentTypes.push_back(parentType);
|
||||||
|
childType->setDirty(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
PrimitiveType *PrimitiveType::parseAndFind(Context &context, Domain &domain)
|
||||||
|
{
|
||||||
|
auto &types = domain.types();
|
||||||
|
|
||||||
|
context.parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
const auto typeName = context.parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
if (typeName.empty())
|
||||||
|
throw utils::ParserException(context.parser, "no type supplied");
|
||||||
|
|
||||||
|
const auto match = std::find_if(types.cbegin(), types.cend(),
|
||||||
|
[&](const auto &primitiveType)
|
||||||
|
{
|
||||||
|
return primitiveType->name() == typeName;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (match == types.cend())
|
||||||
|
{
|
||||||
|
// Only "object" is allowed as an implicit type
|
||||||
|
if (typeName == "object" || typeName == "objects")
|
||||||
|
{
|
||||||
|
context.logger.logWarning(context.parser, "primitive type “" + typeName + "” should be declared");
|
||||||
|
types.emplace_back(std::make_unique<expressions::PrimitiveType>(typeName));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw utils::ParserException(context.parser, "type “" + typeName + "” used but never declared");
|
||||||
|
|
||||||
|
return types.back().get();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto *type = match->get();
|
||||||
|
type->setDirty();
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void PrimitiveType::setDirty(bool isDirty)
|
||||||
|
{
|
||||||
|
m_isDirty = isDirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool PrimitiveType::isDirty() const
|
||||||
|
{
|
||||||
|
return m_isDirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::string &PrimitiveType::name() const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::vector<const PrimitiveType *> &PrimitiveType::parentTypes() const
|
||||||
|
{
|
||||||
|
return m_parentTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
29
src/plasp/pddl/expressions/Type.cpp
Normal file
29
src/plasp/pddl/expressions/Type.cpp
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#include <plasp/pddl/expressions/Type.h>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/ExpressionContext.h>
|
||||||
|
#include <plasp/pddl/expressions/PrimitiveType.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Type
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const Expression *parseExistingPrimitiveType(Context &context, ExpressionContext &expressionContext)
|
||||||
|
{
|
||||||
|
return PrimitiveType::parseAndFind(context, expressionContext.domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
47
src/plasp/pddl/expressions/Unsupported.cpp
Normal file
47
src/plasp/pddl/expressions/Unsupported.cpp
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#include <plasp/pddl/expressions/Unsupported.h>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Identifier.h>
|
||||||
|
#include <plasp/pddl/IO.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Unsupported
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
UnsupportedPointer Unsupported::parse(Context &context)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
auto expression = std::make_unique<Unsupported>(Unsupported());
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
|
||||||
|
expression->m_type = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
context.logger.logWarning(context.parser, "expression type “" + expression->m_type + "” currently unsupported in this context");
|
||||||
|
|
||||||
|
skipSection(parser);
|
||||||
|
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::string &Unsupported::type() const
|
||||||
|
{
|
||||||
|
return m_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
201
src/plasp/pddl/expressions/Variable.cpp
Normal file
201
src/plasp/pddl/expressions/Variable.cpp
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
#include <plasp/pddl/expressions/Variable.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/Domain.h>
|
||||||
|
#include <plasp/pddl/ExpressionContext.h>
|
||||||
|
#include <plasp/pddl/Identifier.h>
|
||||||
|
#include <plasp/pddl/expressions/Either.h>
|
||||||
|
#include <plasp/pddl/expressions/PrimitiveType.h>
|
||||||
|
#include <plasp/pddl/expressions/Type.h>
|
||||||
|
#include <plasp/utils/ParserException.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Variable
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Variable::Variable()
|
||||||
|
: m_isDirty{false},
|
||||||
|
m_type{nullptr}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Variable::parseDeclaration(Context &context, Variables ¶meters)
|
||||||
|
{
|
||||||
|
context.parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
context.parser.expect<std::string>("?");
|
||||||
|
|
||||||
|
auto variable = std::make_unique<Variable>(Variable());
|
||||||
|
|
||||||
|
variable->m_name = context.parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
// Check if variable of that name already exists in the current scope
|
||||||
|
const auto match = std::find_if(parameters.cbegin(), parameters.cend(),
|
||||||
|
[&](const auto ¶meter)
|
||||||
|
{
|
||||||
|
return parameter->name() == variable->m_name;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (match != parameters.cend())
|
||||||
|
throw utils::ParserException(context.parser, "variable “" + variable->m_name + "” already declared in this scope");
|
||||||
|
|
||||||
|
// Flag variable for potentially upcoming type declaration
|
||||||
|
variable->setDirty();
|
||||||
|
|
||||||
|
parameters.emplace_back(std::move(variable));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Variable::parseTypedDeclaration(Context &context, ExpressionContext &expressionContext)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
auto &variables = expressionContext.parameters;
|
||||||
|
|
||||||
|
// Parse and store variable itself
|
||||||
|
parseDeclaration(context, variables);
|
||||||
|
|
||||||
|
auto &variable = variables.back();
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
// Check if the variable has a type declaration
|
||||||
|
if (!parser.probe('-'))
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto setType =
|
||||||
|
[&](const auto *type)
|
||||||
|
{
|
||||||
|
// Set the argument type for all previously flagged arguments
|
||||||
|
std::for_each(variables.begin(), variables.end(),
|
||||||
|
[&](auto &variable)
|
||||||
|
{
|
||||||
|
if (!variable->isDirty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
variable->setType(type);
|
||||||
|
variable->setDirty(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
// Parse argument of "either" type (always begins with opening parenthesis)
|
||||||
|
if ((variable->m_eitherExpression = Either::parse(context, expressionContext, parseExistingPrimitiveType)))
|
||||||
|
{
|
||||||
|
setType(variable->m_eitherExpression.get());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse primitive type
|
||||||
|
const auto *type = PrimitiveType::parseAndFind(context, expressionContext.domain);
|
||||||
|
|
||||||
|
setType(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Variable::parseTypedDeclarations(Context &context, ExpressionContext &expressionContext)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
while (parser.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
parseTypedDeclaration(context, expressionContext);
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expressionContext.parameters.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check correct use of typing requirement
|
||||||
|
const auto typingUsed = (expressionContext.parameters.back()->type() != nullptr);
|
||||||
|
|
||||||
|
// If types are given, check that typing is a requirement
|
||||||
|
if (typingUsed)
|
||||||
|
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, "variable has undeclared type");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const Variable *Variable::parseAndFind(Context &context, const ExpressionContext &expressionContext)
|
||||||
|
{
|
||||||
|
context.parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
context.parser.expect<std::string>("?");
|
||||||
|
|
||||||
|
const auto variableName = context.parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
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 utils::ParserException(context.parser, "parameter “" + variableName + "” used but never declared");
|
||||||
|
|
||||||
|
return match->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::string &Variable::name() const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const Expression *Variable::type() const
|
||||||
|
{
|
||||||
|
return m_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Variable::setDirty(bool isDirty)
|
||||||
|
{
|
||||||
|
m_isDirty = isDirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool Variable::isDirty() const
|
||||||
|
{
|
||||||
|
return m_isDirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Variable::setType(const Expression *type)
|
||||||
|
{
|
||||||
|
m_type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -4,8 +4,6 @@
|
|||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
#include <plasp/utils/Parsing.h>
|
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
namespace sas
|
namespace sas
|
||||||
@@ -33,24 +31,24 @@ AssignedVariable::AssignedVariable(const Variable &variable, const Value &value)
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
AssignedVariable AssignedVariable::fromSAS(std::istream &istream, const Variables &variables)
|
AssignedVariable AssignedVariable::fromSAS(utils::Parser &parser, const Variables &variables)
|
||||||
{
|
{
|
||||||
AssignedVariable assignedVariable;
|
AssignedVariable assignedVariable;
|
||||||
|
|
||||||
assignedVariable.m_variable = &Variable::referenceFromSAS(istream, variables);
|
assignedVariable.m_variable = &Variable::referenceFromSAS(parser, variables);
|
||||||
assignedVariable.m_value = &Value::referenceFromSAS(istream, *assignedVariable.m_variable);
|
assignedVariable.m_value = &Value::referenceFromSAS(parser, *assignedVariable.m_variable);
|
||||||
|
|
||||||
return assignedVariable;
|
return assignedVariable;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
AssignedVariable AssignedVariable::fromSAS(std::istream &istream, const Variable &variable)
|
AssignedVariable AssignedVariable::fromSAS(utils::Parser &parser, const Variable &variable)
|
||||||
{
|
{
|
||||||
AssignedVariable assignedVariable;
|
AssignedVariable assignedVariable;
|
||||||
|
|
||||||
assignedVariable.m_variable = &variable;
|
assignedVariable.m_variable = &variable;
|
||||||
assignedVariable.m_value = &Value::referenceFromSAS(istream, *assignedVariable.m_variable);
|
assignedVariable.m_value = &Value::referenceFromSAS(parser, *assignedVariable.m_variable);
|
||||||
|
|
||||||
return assignedVariable;
|
return assignedVariable;
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,6 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <plasp/sas/VariableTransition.h>
|
#include <plasp/sas/VariableTransition.h>
|
||||||
#include <plasp/utils/Parsing.h>
|
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
@@ -24,24 +23,24 @@ AxiomRule::AxiomRule(AxiomRule::Conditions conditions, AxiomRule::Condition post
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
AxiomRule AxiomRule::fromSAS(std::istream &istream, const Variables &variables)
|
AxiomRule AxiomRule::fromSAS(utils::Parser &parser, const Variables &variables)
|
||||||
{
|
{
|
||||||
utils::parseExpected<std::string>(istream, "begin_rule");
|
parser.expect<std::string>("begin_rule");
|
||||||
|
|
||||||
const auto numberOfConditions = utils::parse<size_t>(istream);
|
const auto numberOfConditions = parser.parse<size_t>();
|
||||||
|
|
||||||
Conditions conditions;
|
Conditions conditions;
|
||||||
conditions.reserve(numberOfConditions);
|
conditions.reserve(numberOfConditions);
|
||||||
|
|
||||||
for (size_t j = 0; j < numberOfConditions; j++)
|
for (size_t j = 0; j < numberOfConditions; j++)
|
||||||
conditions.emplace_back(Condition::fromSAS(istream, variables));
|
conditions.emplace_back(Condition::fromSAS(parser, variables));
|
||||||
|
|
||||||
const auto variableTransition = VariableTransition::fromSAS(istream, variables);
|
const auto variableTransition = VariableTransition::fromSAS(parser, variables);
|
||||||
|
|
||||||
if (&variableTransition.valueBefore() != &Value::Any)
|
if (&variableTransition.valueBefore() != &Value::Any)
|
||||||
conditions.emplace_back(Condition(variableTransition.variable(), variableTransition.valueBefore()));
|
conditions.emplace_back(Condition(variableTransition.variable(), variableTransition.valueBefore()));
|
||||||
|
|
||||||
utils::parseExpected<std::string>(istream, "end_rule");
|
parser.expect<std::string>("end_rule");
|
||||||
|
|
||||||
const Condition postcondition(variableTransition.variable(), variableTransition.valueAfter());
|
const Condition postcondition(variableTransition.variable(), variableTransition.valueAfter());
|
||||||
const AxiomRule axiomRule(std::move(conditions), std::move(postcondition));
|
const AxiomRule axiomRule(std::move(conditions), std::move(postcondition));
|
||||||
|
@@ -13,7 +13,7 @@ namespace sas
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::ostream &operator >>(std::ostream &ostream, const Description &description)
|
utils::LogStream &operator<<(utils::LogStream &ostream, const Description &description)
|
||||||
{
|
{
|
||||||
// Metric section
|
// Metric section
|
||||||
ostream << "uses action costs: " << (description.usesActionCosts() ? "yes" : "no") << std::endl;
|
ostream << "uses action costs: " << (description.usesActionCosts() ? "yes" : "no") << std::endl;
|
||||||
|
@@ -8,7 +8,6 @@
|
|||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
#include <plasp/utils/ParserException.h>
|
#include <plasp/utils/ParserException.h>
|
||||||
#include <plasp/utils/Parsing.h>
|
|
||||||
#include <plasp/sas/VariableTransition.h>
|
#include <plasp/sas/VariableTransition.h>
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
@@ -29,22 +28,25 @@ Description::Description()
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Description Description::fromParser(utils::Parser &&parser)
|
||||||
|
{
|
||||||
|
parser.setCaseSensitive(true);
|
||||||
|
|
||||||
|
Description description;
|
||||||
|
description.parseContent(parser);
|
||||||
|
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Description Description::fromStream(std::istream &istream)
|
Description Description::fromStream(std::istream &istream)
|
||||||
{
|
{
|
||||||
|
utils::Parser parser;
|
||||||
|
parser.readStream("std::cin", istream);
|
||||||
|
|
||||||
Description description;
|
Description description;
|
||||||
|
description.parseContent(parser);
|
||||||
std::setlocale(LC_NUMERIC, "C");
|
|
||||||
|
|
||||||
istream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
|
||||||
|
|
||||||
description.parseVersionSection(istream);
|
|
||||||
description.parseMetricSection(istream);
|
|
||||||
description.parseVariablesSection(istream);
|
|
||||||
description.parseMutexSection(istream);
|
|
||||||
description.parseInitialStateSection(istream);
|
|
||||||
description.parseGoalSection(istream);
|
|
||||||
description.parseOperatorSection(istream);
|
|
||||||
description.parseAxiomSection(istream);
|
|
||||||
|
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
@@ -54,11 +56,15 @@ Description Description::fromStream(std::istream &istream)
|
|||||||
Description Description::fromFile(const boost::filesystem::path &path)
|
Description Description::fromFile(const boost::filesystem::path &path)
|
||||||
{
|
{
|
||||||
if (!boost::filesystem::is_regular_file(path))
|
if (!boost::filesystem::is_regular_file(path))
|
||||||
throw std::runtime_error("File does not exist: \"" + path.string() + "\"");
|
throw std::runtime_error("File does not exist: “" + path.string() + "”");
|
||||||
|
|
||||||
std::ifstream fileStream(path.string(), std::ios::in);
|
utils::Parser parser;
|
||||||
|
parser.readFile(path);
|
||||||
|
|
||||||
return Description::fromStream(fileStream);
|
Description description;
|
||||||
|
description.parseContent(parser);
|
||||||
|
|
||||||
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -149,85 +155,104 @@ bool Description::usesConditionalEffects() const
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Description::parseVersionSection(std::istream &istream) const
|
void Description::parseContent(utils::Parser &parser)
|
||||||
{
|
{
|
||||||
utils::parseExpected<std::string>(istream, "begin_version");
|
parseVersionSection(parser);
|
||||||
|
parseMetricSection(parser);
|
||||||
|
parseVariablesSection(parser);
|
||||||
|
parseMutexSection(parser);
|
||||||
|
parseInitialStateSection(parser);
|
||||||
|
parseGoalSection(parser);
|
||||||
|
parseOperatorSection(parser);
|
||||||
|
parseAxiomSection(parser);
|
||||||
|
|
||||||
const auto formatVersion = utils::parse<size_t>(istream);
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
if (!parser.atEndOfStream())
|
||||||
|
throw utils::ParserException(parser, "expected end of SAS description (perhaps, input contains two SAS descriptions?)");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Description::parseVersionSection(utils::Parser &parser) const
|
||||||
|
{
|
||||||
|
parser.expect<std::string>("begin_version");
|
||||||
|
|
||||||
|
const auto formatVersion = parser.parse<size_t>();
|
||||||
|
|
||||||
if (formatVersion != 3)
|
if (formatVersion != 3)
|
||||||
throw utils::ParserException("Unsupported SAS format version (" + std::to_string(formatVersion) + ")");
|
throw utils::ParserException(parser, "unsupported SAS format version (" + std::to_string(formatVersion) + ")");
|
||||||
|
|
||||||
utils::parseExpected<std::string>(istream, "end_version");
|
parser.expect<std::string>("end_version");
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Description::parseMetricSection(std::istream &istream)
|
void Description::parseMetricSection(utils::Parser &parser)
|
||||||
{
|
{
|
||||||
utils::parseExpected<std::string>(istream, "begin_metric");
|
parser.expect<std::string>("begin_metric");
|
||||||
|
|
||||||
m_usesActionCosts = utils::parse<bool>(istream);
|
m_usesActionCosts = parser.parse<bool>();
|
||||||
|
|
||||||
utils::parseExpected<std::string>(istream, "end_metric");
|
parser.expect<std::string>("end_metric");
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Description::parseVariablesSection(std::istream &istream)
|
void Description::parseVariablesSection(utils::Parser &parser)
|
||||||
{
|
{
|
||||||
const auto numberOfVariables = utils::parse<size_t>(istream);
|
const auto numberOfVariables = parser.parse<size_t>();
|
||||||
m_variables.reserve(numberOfVariables);
|
m_variables.reserve(numberOfVariables);
|
||||||
|
|
||||||
for (size_t i = 0; i < numberOfVariables; i++)
|
for (size_t i = 0; i < numberOfVariables; i++)
|
||||||
m_variables.emplace_back(Variable::fromSAS(istream));
|
m_variables.emplace_back(Variable::fromSAS(parser));
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Description::parseMutexSection(std::istream &istream)
|
void Description::parseMutexSection(utils::Parser &parser)
|
||||||
{
|
{
|
||||||
const auto numberOfMutexGroups = utils::parse<size_t>(istream);
|
const auto numberOfMutexGroups = parser.parse<size_t>();
|
||||||
m_mutexGroups.reserve(numberOfMutexGroups);
|
m_mutexGroups.reserve(numberOfMutexGroups);
|
||||||
|
|
||||||
for (size_t i = 0; i < numberOfMutexGroups; i++)
|
for (size_t i = 0; i < numberOfMutexGroups; i++)
|
||||||
m_mutexGroups.emplace_back(MutexGroup::fromSAS(istream, m_variables));
|
m_mutexGroups.emplace_back(MutexGroup::fromSAS(parser, m_variables));
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Description::parseInitialStateSection(std::istream &istream)
|
void Description::parseInitialStateSection(utils::Parser &parser)
|
||||||
{
|
{
|
||||||
m_initialState = std::make_unique<InitialState>(InitialState::fromSAS(istream, m_variables));
|
m_initialState = std::make_unique<InitialState>(InitialState::fromSAS(parser, m_variables));
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Description::parseGoalSection(std::istream &istream)
|
void Description::parseGoalSection(utils::Parser &parser)
|
||||||
{
|
{
|
||||||
m_goal = std::make_unique<Goal>(Goal::fromSAS(istream, m_variables));
|
m_goal = std::make_unique<Goal>(Goal::fromSAS(parser, m_variables));
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Description::parseOperatorSection(std::istream &istream)
|
void Description::parseOperatorSection(utils::Parser &parser)
|
||||||
{
|
{
|
||||||
const auto numberOfOperators = utils::parse<size_t>(istream);
|
const auto numberOfOperators = parser.parse<size_t>();
|
||||||
m_operators.reserve(numberOfOperators);
|
m_operators.reserve(numberOfOperators);
|
||||||
|
|
||||||
for (size_t i = 0; i < numberOfOperators; i++)
|
for (size_t i = 0; i < numberOfOperators; i++)
|
||||||
m_operators.emplace_back(Operator::fromSAS(istream, m_variables));
|
m_operators.emplace_back(Operator::fromSAS(parser, m_variables));
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Description::parseAxiomSection(std::istream &istream)
|
void Description::parseAxiomSection(utils::Parser &parser)
|
||||||
{
|
{
|
||||||
const auto numberOfAxiomRules = utils::parse<size_t>(istream);
|
const auto numberOfAxiomRules = parser.parse<size_t>();
|
||||||
m_axiomRules.reserve(numberOfAxiomRules);
|
m_axiomRules.reserve(numberOfAxiomRules);
|
||||||
|
|
||||||
for (size_t i = 0; i < numberOfAxiomRules; i++)
|
for (size_t i = 0; i < numberOfAxiomRules; i++)
|
||||||
m_axiomRules.emplace_back(AxiomRule::fromSAS(istream, m_variables));
|
m_axiomRules.emplace_back(AxiomRule::fromSAS(parser, m_variables));
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@@ -3,7 +3,6 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <plasp/sas/VariableTransition.h>
|
#include <plasp/sas/VariableTransition.h>
|
||||||
#include <plasp/utils/Parsing.h>
|
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
@@ -24,17 +23,17 @@ Effect::Effect(Conditions conditions, Condition postcondition)
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Effect Effect::fromSAS(std::istream &istream, const Variables &variables, Conditions &preconditions)
|
Effect Effect::fromSAS(utils::Parser &parser, const Variables &variables, Conditions &preconditions)
|
||||||
{
|
{
|
||||||
Effect::Conditions conditions;
|
Effect::Conditions conditions;
|
||||||
|
|
||||||
const auto numberOfEffectConditions = utils::parse<size_t>(istream);
|
const auto numberOfEffectConditions = parser.parse<size_t>();
|
||||||
conditions.reserve(numberOfEffectConditions);
|
conditions.reserve(numberOfEffectConditions);
|
||||||
|
|
||||||
for (size_t k = 0; k < numberOfEffectConditions; k++)
|
for (size_t k = 0; k < numberOfEffectConditions; k++)
|
||||||
conditions.emplace_back(Condition::fromSAS(istream, variables));
|
conditions.emplace_back(Condition::fromSAS(parser, variables));
|
||||||
|
|
||||||
const auto variableTransition = VariableTransition::fromSAS(istream, variables);
|
const auto variableTransition = VariableTransition::fromSAS(parser, variables);
|
||||||
|
|
||||||
if (&variableTransition.valueBefore() != &Value::Any)
|
if (&variableTransition.valueBefore() != &Value::Any)
|
||||||
preconditions.emplace_back(Condition(variableTransition.variable(), variableTransition.valueBefore()));
|
preconditions.emplace_back(Condition(variableTransition.variable(), variableTransition.valueBefore()));
|
||||||
|
@@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <plasp/utils/Parsing.h>
|
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
namespace sas
|
namespace sas
|
||||||
@@ -15,19 +13,19 @@ namespace sas
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Goal Goal::fromSAS(std::istream &istream, const Variables &variables)
|
Goal Goal::fromSAS(utils::Parser &parser, const Variables &variables)
|
||||||
{
|
{
|
||||||
Goal goal;
|
Goal goal;
|
||||||
|
|
||||||
utils::parseExpected<std::string>(istream, "begin_goal");
|
parser.expect<std::string>("begin_goal");
|
||||||
|
|
||||||
const auto numberOfGoalFacts = utils::parse<size_t>(istream);
|
const auto numberOfGoalFacts = parser.parse<size_t>();
|
||||||
goal.m_facts.reserve(numberOfGoalFacts);
|
goal.m_facts.reserve(numberOfGoalFacts);
|
||||||
|
|
||||||
for (size_t i = 0; i < numberOfGoalFacts; i++)
|
for (size_t i = 0; i < numberOfGoalFacts; i++)
|
||||||
goal.m_facts.emplace_back(Fact::fromSAS(istream, variables));
|
goal.m_facts.emplace_back(Fact::fromSAS(parser, variables));
|
||||||
|
|
||||||
utils::parseExpected<std::string>(istream, "end_goal");
|
parser.expect<std::string>("end_goal");
|
||||||
|
|
||||||
return goal;
|
return goal;
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,5 @@
|
|||||||
#include <plasp/sas/InitialState.h>
|
#include <plasp/sas/InitialState.h>
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <plasp/utils/Parsing.h>
|
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
namespace sas
|
namespace sas
|
||||||
@@ -15,18 +11,18 @@ namespace sas
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
InitialState InitialState::fromSAS(std::istream &istream, const Variables &variables)
|
InitialState InitialState::fromSAS(utils::Parser &parser, const Variables &variables)
|
||||||
{
|
{
|
||||||
InitialState initialState;
|
InitialState initialState;
|
||||||
|
|
||||||
utils::parseExpected<std::string>(istream, "begin_state");
|
parser.expect<std::string>("begin_state");
|
||||||
|
|
||||||
initialState.m_facts.reserve(variables.size());
|
initialState.m_facts.reserve(variables.size());
|
||||||
|
|
||||||
for (size_t i = 0; i < variables.size(); i++)
|
for (size_t i = 0; i < variables.size(); i++)
|
||||||
initialState.m_facts.emplace_back(Fact::fromSAS(istream, variables[i]));
|
initialState.m_facts.emplace_back(Fact::fromSAS(parser, variables[i]));
|
||||||
|
|
||||||
utils::parseExpected<std::string>(istream, "end_state");
|
parser.expect<std::string>("end_state");
|
||||||
|
|
||||||
return initialState;
|
return initialState;
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <plasp/utils/Parsing.h>
|
#include <plasp/utils/ParserException.h>
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
@@ -15,24 +15,24 @@ namespace sas
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
MutexGroup MutexGroup::fromSAS(std::istream &istream, const Variables &variables)
|
MutexGroup MutexGroup::fromSAS(utils::Parser &parser, const Variables &variables)
|
||||||
{
|
{
|
||||||
MutexGroup mutexGroup;
|
MutexGroup mutexGroup;
|
||||||
|
|
||||||
utils::parseExpected<std::string>(istream, "begin_mutex_group");
|
parser.expect<std::string>("begin_mutex_group");
|
||||||
|
|
||||||
const auto numberOfFacts = utils::parse<size_t>(istream);
|
const auto numberOfFacts = parser.parse<size_t>();
|
||||||
mutexGroup.m_facts.reserve(numberOfFacts);
|
mutexGroup.m_facts.reserve(numberOfFacts);
|
||||||
|
|
||||||
for (size_t j = 0; j < numberOfFacts; j++)
|
for (size_t j = 0; j < numberOfFacts; j++)
|
||||||
{
|
{
|
||||||
mutexGroup.m_facts.emplace_back(Fact::fromSAS(istream, variables));
|
mutexGroup.m_facts.emplace_back(Fact::fromSAS(parser, variables));
|
||||||
|
|
||||||
if (mutexGroup.m_facts[j].value() == Value::None)
|
if (mutexGroup.m_facts[j].value() == Value::None)
|
||||||
throw utils::ParserException("Mutex groups must not contain <none of those> values");
|
throw utils::ParserException(parser, "mutex groups must not contain <none of those> values");
|
||||||
}
|
}
|
||||||
|
|
||||||
utils::parseExpected<std::string>(istream, "end_mutex_group");
|
parser.expect<std::string>("end_mutex_group");
|
||||||
|
|
||||||
return mutexGroup;
|
return mutexGroup;
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
#include <plasp/sas/VariableTransition.h>
|
#include <plasp/sas/VariableTransition.h>
|
||||||
#include <plasp/utils/Parsing.h>
|
#include <plasp/utils/Formatting.h>
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
@@ -17,40 +17,40 @@ namespace sas
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Operator Operator::fromSAS(std::istream &istream, const Variables &variables)
|
Operator Operator::fromSAS(utils::Parser &parser, const Variables &variables)
|
||||||
{
|
{
|
||||||
Operator operator_;
|
Operator operator_;
|
||||||
|
|
||||||
utils::parseExpected<std::string>(istream, "begin_operator");
|
parser.expect<std::string>("begin_operator");
|
||||||
|
|
||||||
operator_.m_predicate = Predicate::fromSAS(istream);
|
operator_.m_predicate = Predicate::fromSAS(parser);
|
||||||
|
|
||||||
const auto numberOfPrevailConditions = utils::parse<size_t>(istream);
|
const auto numberOfPrevailConditions = parser.parse<size_t>();
|
||||||
operator_.m_preconditions.reserve(numberOfPrevailConditions);
|
operator_.m_preconditions.reserve(numberOfPrevailConditions);
|
||||||
|
|
||||||
for (size_t j = 0; j < numberOfPrevailConditions; j++)
|
for (size_t j = 0; j < numberOfPrevailConditions; j++)
|
||||||
operator_.m_preconditions.emplace_back(Condition::fromSAS(istream, variables));
|
operator_.m_preconditions.emplace_back(Condition::fromSAS(parser, variables));
|
||||||
|
|
||||||
const auto numberOfEffects = utils::parse<size_t>(istream);
|
const auto numberOfEffects = parser.parse<size_t>();
|
||||||
operator_.m_effects.reserve(numberOfEffects);
|
operator_.m_effects.reserve(numberOfEffects);
|
||||||
|
|
||||||
for (size_t j = 0; j < numberOfEffects; j++)
|
for (size_t j = 0; j < numberOfEffects; j++)
|
||||||
operator_.m_effects.emplace_back(Effect::fromSAS(istream, variables, operator_.m_preconditions));
|
operator_.m_effects.emplace_back(Effect::fromSAS(parser, variables, operator_.m_preconditions));
|
||||||
|
|
||||||
operator_.m_costs = utils::parse<size_t>(istream);
|
operator_.m_costs = parser.parse<size_t>();
|
||||||
|
|
||||||
utils::parseExpected<std::string>(istream, "end_operator");
|
parser.expect<std::string>("end_operator");
|
||||||
|
|
||||||
return operator_;
|
return operator_;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Operator::printPredicateAsASP(std::ostream &ostream) const
|
void Operator::printPredicateAsASP(utils::LogStream &outputStream) const
|
||||||
{
|
{
|
||||||
ostream << "action(";
|
outputStream << utils::Keyword("action") << "(";
|
||||||
m_predicate.printAsASP(ostream);
|
m_predicate.printAsASP(outputStream);
|
||||||
ostream << ")";
|
outputStream << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@@ -4,7 +4,8 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include <plasp/utils/Parsing.h>
|
#include <plasp/utils/IO.h>
|
||||||
|
#include <plasp/utils/ParserException.h>
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
@@ -17,31 +18,35 @@ namespace sas
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Predicate Predicate::fromSAS(std::istream &istream)
|
Predicate Predicate::fromSAS(utils::Parser &parser)
|
||||||
{
|
{
|
||||||
Predicate predicate;
|
Predicate predicate;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
istream.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
parser.skipLine();
|
||||||
|
|
||||||
// TODO: Inefficient, reimplement in one pass
|
predicate.m_name = parser.parse<std::string>();
|
||||||
std::string line;
|
|
||||||
std::getline(istream, line);
|
|
||||||
|
|
||||||
std::stringstream lineStream(line);
|
while (true)
|
||||||
|
{
|
||||||
|
// Parse arguments until reaching newline
|
||||||
|
parser.skipWhiteSpace(
|
||||||
|
[&](const auto character)
|
||||||
|
{
|
||||||
|
return character != '\n' && std::isspace(character);
|
||||||
|
});
|
||||||
|
|
||||||
predicate.m_name = utils::parse<std::string>(lineStream);
|
if (parser.currentCharacter() == '\n')
|
||||||
|
break;
|
||||||
|
|
||||||
while (lineStream.peek() == ' ')
|
const auto value = parser.parse<std::string>();
|
||||||
lineStream.ignore(1);
|
predicate.m_arguments.emplace_back(std::move(value));
|
||||||
|
}
|
||||||
for (std::string argument; std::getline(lineStream, argument, ' ');)
|
|
||||||
predicate.m_arguments.push_back(std::move(argument));
|
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception &e)
|
||||||
{
|
{
|
||||||
throw utils::ParserException("Could not parse operator predicate");
|
throw utils::ParserException(parser, "could not parse operator predicate");
|
||||||
}
|
}
|
||||||
|
|
||||||
return predicate;
|
return predicate;
|
||||||
@@ -63,43 +68,43 @@ const Predicate::Arguments &Predicate::arguments() const
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Predicate::printAsSAS(std::ostream &ostream) const
|
void Predicate::printAsSAS(utils::LogStream &outputStream) const
|
||||||
{
|
{
|
||||||
if (m_arguments.empty())
|
if (m_arguments.empty())
|
||||||
{
|
{
|
||||||
ostream << m_name;
|
outputStream << m_name;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < m_arguments.size(); i++)
|
for (size_t i = 0; i < m_arguments.size(); i++)
|
||||||
{
|
{
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
ostream << " ";
|
outputStream << " ";
|
||||||
|
|
||||||
ostream << m_arguments[i];
|
outputStream << m_arguments[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Predicate::printAsASP(std::ostream &ostream) const
|
void Predicate::printAsASP(utils::LogStream &outputStream) const
|
||||||
{
|
{
|
||||||
if (m_arguments.empty())
|
if (m_arguments.empty())
|
||||||
{
|
{
|
||||||
ostream << utils::escapeASP(m_name);
|
outputStream << utils::escapeASP(m_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ostream << utils::escapeASP(m_name) << "(";
|
outputStream << utils::escapeASP(m_name) << "(";
|
||||||
|
|
||||||
for (size_t i = 0; i < m_arguments.size(); i++)
|
for (size_t i = 0; i < m_arguments.size(); i++)
|
||||||
{
|
{
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
ostream << ", ";
|
outputStream << ", ";
|
||||||
|
|
||||||
ostream << utils::escapeASP(m_arguments[i]);
|
outputStream << utils::escapeASP(m_arguments[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ostream << ")";
|
outputStream << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
#include <plasp/sas/TranslatorASP.h>
|
#include <plasp/sas/TranslatorASP.h>
|
||||||
|
|
||||||
#include <plasp/sas/TranslatorException.h>
|
#include <plasp/utils/Formatting.h>
|
||||||
#include <plasp/utils/Parsing.h>
|
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
@@ -14,62 +13,90 @@ namespace sas
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
TranslatorASP::TranslatorASP(const Description &description)
|
TranslatorASP::TranslatorASP(const Description &description, utils::LogStream &ostream)
|
||||||
: m_description(description)
|
: m_description(description),
|
||||||
|
m_outputStream(ostream)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void TranslatorASP::translate(std::ostream &ostream) const
|
void TranslatorASP::translate() const
|
||||||
{
|
{
|
||||||
const auto usesActionCosts = m_description.usesActionCosts();
|
translateRequirements();
|
||||||
const auto usesAxiomRules = m_description.usesAxiomRules();
|
translateInitialState();
|
||||||
const auto usesConditionalEffects = m_description.usesConditionalEffects();
|
translateGoal();
|
||||||
|
translateVariables();
|
||||||
|
translateActions();
|
||||||
|
translateMutexes();
|
||||||
|
translateAxiomRules();
|
||||||
|
}
|
||||||
|
|
||||||
ostream << "% feature requirements" << std::endl;
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
if (usesActionCosts)
|
void TranslatorASP::translateRequirements() const
|
||||||
ostream << "requiresFeature(actionCosts)." << std::endl;
|
{
|
||||||
|
m_outputStream << utils::Heading2("feature requirements") << std::endl;
|
||||||
|
|
||||||
if (usesAxiomRules)
|
if (m_description.usesActionCosts())
|
||||||
ostream << "requiresFeature(axiomRules)." << std::endl;
|
m_outputStream << utils::Keyword("requiresFeature") << "(actionCosts)." << std::endl;
|
||||||
|
|
||||||
if (usesConditionalEffects)
|
if (m_description.usesAxiomRules())
|
||||||
ostream << "requiresFeature(conditionalEffects)." << std::endl;
|
m_outputStream << utils::Keyword("requiresFeature") << "(axiomRules)." << std::endl;
|
||||||
|
|
||||||
ostream << std::endl;
|
if (m_description.usesConditionalEffects())
|
||||||
ostream << "% initial state" << std::endl;
|
m_outputStream << utils::Keyword("requiresFeature") << "(conditionalEffects)." << std::endl;
|
||||||
|
|
||||||
|
m_outputStream << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TranslatorASP::translateInitialState() const
|
||||||
|
{
|
||||||
|
m_outputStream << utils::Heading2("initial state") << std::endl;
|
||||||
|
|
||||||
const auto &initialStateFacts = m_description.initialState().facts();
|
const auto &initialStateFacts = m_description.initialState().facts();
|
||||||
|
|
||||||
std::for_each(initialStateFacts.cbegin(), initialStateFacts.cend(),
|
std::for_each(initialStateFacts.cbegin(), initialStateFacts.cend(),
|
||||||
[&](const auto &fact)
|
[&](const auto &fact)
|
||||||
{
|
{
|
||||||
ostream << "initialState(";
|
m_outputStream << utils::Keyword("initialState") << "(";
|
||||||
fact.variable().printNameAsASPPredicate(ostream);
|
fact.variable().printNameAsASPPredicate(m_outputStream);
|
||||||
ostream << ", ";
|
m_outputStream << ", ";
|
||||||
fact.value().printAsASPPredicate(ostream);
|
fact.value().printAsASPPredicate(m_outputStream);
|
||||||
ostream << ")." << std::endl;
|
m_outputStream << ")." << std::endl;
|
||||||
});
|
});
|
||||||
|
|
||||||
ostream << std::endl;
|
m_outputStream << std::endl;
|
||||||
ostream << "% goal" << std::endl;
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TranslatorASP::translateGoal() const
|
||||||
|
{
|
||||||
|
m_outputStream << utils::Heading2("goal") << std::endl;
|
||||||
|
|
||||||
const auto &goalFacts = m_description.goal().facts();
|
const auto &goalFacts = m_description.goal().facts();
|
||||||
|
|
||||||
std::for_each(goalFacts.cbegin(), goalFacts.cend(),
|
std::for_each(goalFacts.cbegin(), goalFacts.cend(),
|
||||||
[&](const auto &fact)
|
[&](const auto &fact)
|
||||||
{
|
{
|
||||||
ostream << "goal(";
|
m_outputStream << utils::Keyword("goal") << "(";
|
||||||
fact.variable().printNameAsASPPredicate(ostream);
|
fact.variable().printNameAsASPPredicate(m_outputStream);
|
||||||
ostream << ", ";
|
m_outputStream << ", ";
|
||||||
fact.value().printAsASPPredicate(ostream);
|
fact.value().printAsASPPredicate(m_outputStream);
|
||||||
ostream << ")." << std::endl;
|
m_outputStream << ")." << std::endl;
|
||||||
});
|
});
|
||||||
|
|
||||||
ostream << std::endl;
|
m_outputStream << std::endl;
|
||||||
ostream << "% variables";
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TranslatorASP::translateVariables() const
|
||||||
|
{
|
||||||
|
m_outputStream << utils::Heading2("variables");
|
||||||
|
|
||||||
const auto &variables = m_description.variables();
|
const auto &variables = m_description.variables();
|
||||||
|
|
||||||
@@ -80,45 +107,51 @@ void TranslatorASP::translate(std::ostream &ostream) const
|
|||||||
|
|
||||||
BOOST_ASSERT(!values.empty());
|
BOOST_ASSERT(!values.empty());
|
||||||
|
|
||||||
ostream << std::endl;
|
m_outputStream << std::endl;
|
||||||
variable.printNameAsASPPredicate(ostream);
|
variable.printNameAsASPPredicate(m_outputStream);
|
||||||
ostream << "." << std::endl;
|
m_outputStream << "." << std::endl;
|
||||||
|
|
||||||
std::for_each(values.cbegin(), values.cend(),
|
std::for_each(values.cbegin(), values.cend(),
|
||||||
[&](const auto &value)
|
[&](const auto &value)
|
||||||
{
|
{
|
||||||
ostream << "contains(";
|
m_outputStream << utils::Keyword("contains") << "(";
|
||||||
variable.printNameAsASPPredicate(ostream);
|
variable.printNameAsASPPredicate(m_outputStream);
|
||||||
ostream << ", ";
|
m_outputStream << ", ";
|
||||||
value.printAsASPPredicate(ostream);
|
value.printAsASPPredicate(m_outputStream);
|
||||||
ostream << ")." << std::endl;
|
m_outputStream << ")." << std::endl;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
ostream << std::endl;
|
m_outputStream << std::endl;
|
||||||
ostream << "% actions";
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TranslatorASP::translateActions() const
|
||||||
|
{
|
||||||
|
m_outputStream << utils::Heading2("actions");
|
||||||
|
|
||||||
const auto &operators = m_description.operators();
|
const auto &operators = m_description.operators();
|
||||||
|
|
||||||
std::for_each(operators.cbegin(), operators.cend(),
|
std::for_each(operators.cbegin(), operators.cend(),
|
||||||
[&](const auto &operator_)
|
[&](const auto &operator_)
|
||||||
{
|
{
|
||||||
ostream << std::endl;
|
m_outputStream << std::endl;
|
||||||
operator_.printPredicateAsASP(ostream);
|
operator_.printPredicateAsASP(m_outputStream);
|
||||||
ostream << "." << std::endl;
|
m_outputStream << "." << std::endl;
|
||||||
|
|
||||||
const auto &preconditions = operator_.preconditions();
|
const auto &preconditions = operator_.preconditions();
|
||||||
|
|
||||||
std::for_each(preconditions.cbegin(), preconditions.cend(),
|
std::for_each(preconditions.cbegin(), preconditions.cend(),
|
||||||
[&](const auto &precondition)
|
[&](const auto &precondition)
|
||||||
{
|
{
|
||||||
ostream << "precondition(";
|
m_outputStream << utils::Keyword("precondition") << "(";
|
||||||
operator_.printPredicateAsASP(ostream);
|
operator_.printPredicateAsASP(m_outputStream);
|
||||||
ostream << ", ";
|
m_outputStream << ", ";
|
||||||
precondition.variable().printNameAsASPPredicate(ostream);
|
precondition.variable().printNameAsASPPredicate(m_outputStream);
|
||||||
ostream << ", ";
|
m_outputStream << ", ";
|
||||||
precondition.value().printAsASPPredicate(ostream);
|
precondition.value().printAsASPPredicate(m_outputStream);
|
||||||
ostream << ")." << std::endl;
|
m_outputStream << ")." << std::endl;
|
||||||
});
|
});
|
||||||
|
|
||||||
const auto &effects = operator_.effects();
|
const auto &effects = operator_.effects();
|
||||||
@@ -133,33 +166,39 @@ void TranslatorASP::translate(std::ostream &ostream) const
|
|||||||
std::for_each(conditions.cbegin(), conditions.cend(),
|
std::for_each(conditions.cbegin(), conditions.cend(),
|
||||||
[&](const auto &condition)
|
[&](const auto &condition)
|
||||||
{
|
{
|
||||||
ostream << "effectCondition(";
|
m_outputStream << utils::Keyword("effectCondition") << "(";
|
||||||
operator_.printPredicateAsASP(ostream);
|
operator_.printPredicateAsASP(m_outputStream);
|
||||||
ostream << ", effect(" << currentEffectID << "), ";
|
m_outputStream << ", " << utils::Keyword("effect") << "(" << utils::Number(std::to_string(currentEffectID)) << "), ";
|
||||||
condition.variable().printNameAsASPPredicate(ostream);
|
condition.variable().printNameAsASPPredicate(m_outputStream);
|
||||||
ostream << ", ";
|
m_outputStream << ", ";
|
||||||
condition.value().printAsASPPredicate(ostream);
|
condition.value().printAsASPPredicate(m_outputStream);
|
||||||
ostream << ")." << std::endl;
|
m_outputStream << ")." << std::endl;
|
||||||
});
|
});
|
||||||
|
|
||||||
ostream << "postcondition(";
|
m_outputStream << utils::Keyword("postcondition") << "(";
|
||||||
operator_.printPredicateAsASP(ostream);
|
operator_.printPredicateAsASP(m_outputStream);
|
||||||
ostream << ", effect(" << currentEffectID << "), ";
|
m_outputStream << ", " << utils::Keyword("effect") << "(" << utils::Number(std::to_string(currentEffectID)) << "), ";
|
||||||
effect.postcondition().variable().printNameAsASPPredicate(ostream);
|
effect.postcondition().variable().printNameAsASPPredicate(m_outputStream);
|
||||||
ostream << ", ";
|
m_outputStream << ", ";
|
||||||
effect.postcondition().value().printAsASPPredicate(ostream);
|
effect.postcondition().value().printAsASPPredicate(m_outputStream);
|
||||||
ostream << ")." << std::endl;
|
m_outputStream << ")." << std::endl;
|
||||||
|
|
||||||
currentEffectID++;
|
currentEffectID++;
|
||||||
});
|
});
|
||||||
|
|
||||||
ostream << "costs(";
|
m_outputStream << utils::Keyword("costs") << "(";
|
||||||
operator_.printPredicateAsASP(ostream);
|
operator_.printPredicateAsASP(m_outputStream);
|
||||||
ostream << ", " << operator_.costs() << ")." << std::endl;
|
m_outputStream << ", " << operator_.costs() << ")." << std::endl;
|
||||||
});
|
});
|
||||||
|
|
||||||
ostream << std::endl;
|
m_outputStream << std::endl;
|
||||||
ostream << "% mutex groups";
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TranslatorASP::translateMutexes() const
|
||||||
|
{
|
||||||
|
m_outputStream << utils::Heading2("mutex groups");
|
||||||
|
|
||||||
const auto &mutexGroups = m_description.mutexGroups();
|
const auto &mutexGroups = m_description.mutexGroups();
|
||||||
|
|
||||||
@@ -171,59 +210,64 @@ void TranslatorASP::translate(std::ostream &ostream) const
|
|||||||
const auto mutexGroupID = std::to_string(currentMutexGroupID);
|
const auto mutexGroupID = std::to_string(currentMutexGroupID);
|
||||||
currentMutexGroupID++;
|
currentMutexGroupID++;
|
||||||
|
|
||||||
ostream << std::endl << "mutexGroup(" << mutexGroupID << ")." << std::endl;
|
m_outputStream << std::endl << utils::Keyword("mutexGroup") << "(" << utils::Number(mutexGroupID) << ")." << std::endl;
|
||||||
|
|
||||||
const auto &facts = mutexGroup.facts();
|
const auto &facts = mutexGroup.facts();
|
||||||
|
|
||||||
std::for_each(facts.cbegin(), facts.cend(),
|
std::for_each(facts.cbegin(), facts.cend(),
|
||||||
[&](const auto &fact)
|
[&](const auto &fact)
|
||||||
{
|
{
|
||||||
ostream << "contains(mutexGroup(" << mutexGroupID << "), ";
|
m_outputStream << utils::Keyword("contains") << "(" << utils::Keyword("mutexGroup") << "(" << utils::Number(mutexGroupID) << "), ";
|
||||||
fact.variable().printNameAsASPPredicate(ostream);
|
fact.variable().printNameAsASPPredicate(m_outputStream);
|
||||||
ostream << ", ";
|
m_outputStream << ", ";
|
||||||
fact.value().printAsASPPredicate(ostream);
|
fact.value().printAsASPPredicate(m_outputStream);
|
||||||
ostream << ")." << std::endl;
|
m_outputStream << ")." << std::endl;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (usesAxiomRules)
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
{
|
|
||||||
ostream << std::endl;
|
|
||||||
ostream << "% axiom rules";
|
|
||||||
|
|
||||||
const auto &axiomRules = m_description.axiomRules();
|
void TranslatorASP::translateAxiomRules() const
|
||||||
|
{
|
||||||
|
if (!m_description.usesActionCosts())
|
||||||
|
return;
|
||||||
|
|
||||||
size_t currentAxiomRuleID = 0;
|
m_outputStream << std::endl;
|
||||||
|
m_outputStream << utils::Heading2("axiom rules");
|
||||||
|
|
||||||
std::for_each(axiomRules.cbegin(), axiomRules.cend(),
|
const auto &axiomRules = m_description.axiomRules();
|
||||||
[&](const auto &axiomRule)
|
|
||||||
{
|
|
||||||
const auto axiomRuleID = std::to_string(currentAxiomRuleID);
|
|
||||||
currentAxiomRuleID++;
|
|
||||||
|
|
||||||
ostream << std::endl << "axiomRule(" << axiomRuleID << ")." << std::endl;
|
size_t currentAxiomRuleID = 0;
|
||||||
|
|
||||||
const auto &conditions = axiomRule.conditions();
|
std::for_each(axiomRules.cbegin(), axiomRules.cend(),
|
||||||
|
[&](const auto &axiomRule)
|
||||||
|
{
|
||||||
|
const auto axiomRuleID = std::to_string(currentAxiomRuleID);
|
||||||
|
currentAxiomRuleID++;
|
||||||
|
|
||||||
std::for_each(conditions.cbegin(), conditions.cend(),
|
m_outputStream << std::endl << utils::Keyword("axiomRule") << "(" << utils::Number(axiomRuleID) << ")." << std::endl;
|
||||||
[&](const auto &condition)
|
|
||||||
{
|
|
||||||
ostream << "condition(axiomRule(" << axiomRuleID << "), ";
|
|
||||||
condition.variable().printNameAsASPPredicate(ostream);
|
|
||||||
ostream << ", ";
|
|
||||||
condition.value().printAsASPPredicate(ostream);
|
|
||||||
ostream << ")." << std::endl;
|
|
||||||
});
|
|
||||||
|
|
||||||
const auto &postcondition = axiomRule.postcondition();
|
const auto &conditions = axiomRule.conditions();
|
||||||
|
|
||||||
ostream << "postcondition(axiomRule(axiomRule" << axiomRuleID << "), ";
|
std::for_each(conditions.cbegin(), conditions.cend(),
|
||||||
postcondition.variable().printNameAsASPPredicate(ostream);
|
[&](const auto &condition)
|
||||||
ostream << ", ";
|
{
|
||||||
postcondition.value().printAsASPPredicate(ostream);
|
m_outputStream << utils::Keyword("condition") << "(" << utils::Keyword("axiomRule") << "(" << utils::Number(axiomRuleID) << "), ";
|
||||||
ostream << ")." << std::endl;
|
condition.variable().printNameAsASPPredicate(m_outputStream);
|
||||||
});
|
m_outputStream << ", ";
|
||||||
}
|
condition.value().printAsASPPredicate(m_outputStream);
|
||||||
|
m_outputStream << ")." << std::endl;
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto &postcondition = axiomRule.postcondition();
|
||||||
|
|
||||||
|
m_outputStream << utils::Keyword("postcondition") << "(" << utils::Keyword("axiomRule") << "(" << utils::Number(axiomRuleID) << "), ";
|
||||||
|
postcondition.variable().printNameAsASPPredicate(m_outputStream);
|
||||||
|
m_outputStream << ", ";
|
||||||
|
postcondition.value().printAsASPPredicate(m_outputStream);
|
||||||
|
m_outputStream << ")." << std::endl;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@@ -3,7 +3,9 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <plasp/sas/Variable.h>
|
#include <plasp/sas/Variable.h>
|
||||||
#include <plasp/utils/Parsing.h>
|
#include <plasp/utils/Formatting.h>
|
||||||
|
#include <plasp/utils/IO.h>
|
||||||
|
#include <plasp/utils/ParserException.h>
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
@@ -53,14 +55,14 @@ Value Value::negated() const
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Value Value::fromSAS(std::istream &istream)
|
Value Value::fromSAS(utils::Parser &parser)
|
||||||
{
|
{
|
||||||
const auto sasSign = utils::parse<std::string>(istream);
|
const auto sasSign = parser.parse<std::string>();
|
||||||
|
|
||||||
if (sasSign == "<none")
|
if (sasSign == "<none")
|
||||||
{
|
{
|
||||||
utils::parseExpected<std::string>(istream, "of");
|
parser.expect<std::string>("of");
|
||||||
utils::parseExpected<std::string>(istream, "those>");
|
parser.expect<std::string>("those>");
|
||||||
|
|
||||||
// TODO: do not return a copy of Value::None
|
// TODO: do not return a copy of Value::None
|
||||||
return Value::None;
|
return Value::None;
|
||||||
@@ -73,12 +75,12 @@ Value Value::fromSAS(std::istream &istream)
|
|||||||
else if (sasSign == "NegatedAtom")
|
else if (sasSign == "NegatedAtom")
|
||||||
value.m_sign = Value::Sign::Negative;
|
value.m_sign = Value::Sign::Negative;
|
||||||
else
|
else
|
||||||
throw utils::ParserException("Invalid value sign \"" + sasSign + "\"");
|
throw utils::ParserException(parser, "invalid value sign “" + sasSign + "”");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
istream.ignore(1);
|
parser.skipWhiteSpace();
|
||||||
std::getline(istream, value.m_name);
|
value.m_name = parser.getLine();
|
||||||
|
|
||||||
// Remove trailing ()
|
// Remove trailing ()
|
||||||
if (value.m_name.find("()") != std::string::npos)
|
if (value.m_name.find("()") != std::string::npos)
|
||||||
@@ -89,7 +91,7 @@ Value Value::fromSAS(std::istream &istream)
|
|||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception &e)
|
||||||
{
|
{
|
||||||
throw utils::ParserException(std::string("Could not parse variable value (") + e.what() + ")");
|
throw utils::ParserException(parser, std::string("could not parse variable value (") + e.what() + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
@@ -97,15 +99,15 @@ Value Value::fromSAS(std::istream &istream)
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
const Value &Value::referenceFromSAS(std::istream &istream, const Variable &variable)
|
const Value &Value::referenceFromSAS(utils::Parser &parser, const Variable &variable)
|
||||||
{
|
{
|
||||||
const auto valueID = utils::parse<int>(istream);
|
const auto valueID = parser.parse<int>();
|
||||||
|
|
||||||
if (valueID == -1)
|
if (valueID == -1)
|
||||||
return Value::Any;
|
return Value::Any;
|
||||||
|
|
||||||
if (valueID < 0 || static_cast<size_t>(valueID) >= variable.values().size())
|
if (valueID < 0 || static_cast<size_t>(valueID) >= variable.values().size())
|
||||||
throw utils::ParserException("Value index out of range (variable " + variable.name() + ", index " + std::to_string(valueID) + ")");
|
throw utils::ParserException(parser, "value index out of range (variable " + variable.name() + ", index " + std::to_string(valueID) + ")");
|
||||||
|
|
||||||
return variable.values()[valueID];
|
return variable.values()[valueID];
|
||||||
}
|
}
|
||||||
@@ -126,42 +128,42 @@ const std::string &Value::name() const
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Value::printAsASP(std::ostream &ostream) const
|
void Value::printAsASP(utils::LogStream &outputStream) const
|
||||||
{
|
{
|
||||||
if (m_sign == Value::Sign::Negative)
|
if (m_sign == Value::Sign::Negative)
|
||||||
ostream << "not ";
|
outputStream << utils::Keyword("not") << " ";
|
||||||
|
|
||||||
ostream << utils::escapeASP(m_name);
|
outputStream << utils::escapeASP(m_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Value::printAsASPPredicate(std::ostream &ostream) const
|
void Value::printAsASPPredicate(utils::LogStream &outputStream) const
|
||||||
{
|
{
|
||||||
// TODO: do not compare by value
|
// TODO: do not compare by value
|
||||||
if (*this == Value::None)
|
if (*this == Value::None)
|
||||||
{
|
{
|
||||||
ostream << "value(none)";
|
outputStream << utils::Keyword("value") << "(" << utils::Keyword("none") << ")";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ostream << "value(" << utils::escapeASP(m_name) << ", "
|
outputStream << utils::Keyword("value") << "(" << utils::escapeASP(m_name) << ", "
|
||||||
<< (m_sign == Sign::Positive ? "true" : "false") << ")";
|
<< (m_sign == Sign::Positive ? utils::Keyword("true") : utils::Keyword("false")) << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Value::printAsSAS(std::ostream &ostream) const
|
void Value::printAsSAS(utils::LogStream &outputStream) const
|
||||||
{
|
{
|
||||||
if (m_sign == Value::Sign::Positive)
|
if (m_sign == Value::Sign::Positive)
|
||||||
ostream << "Atom ";
|
outputStream << "Atom ";
|
||||||
else
|
else
|
||||||
ostream << "NegatedAtom ";
|
outputStream << "NegatedAtom ";
|
||||||
|
|
||||||
ostream << m_name;
|
outputStream << m_name;
|
||||||
|
|
||||||
if (!m_hasArguments)
|
if (!m_hasArguments)
|
||||||
ostream << "()";
|
outputStream << "()";
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <plasp/utils/Parsing.h>
|
#include <plasp/utils/Formatting.h>
|
||||||
|
#include <plasp/utils/IO.h>
|
||||||
|
#include <plasp/utils/ParserException.h>
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
@@ -22,47 +24,47 @@ Variable::Variable()
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Variable Variable::fromSAS(std::istream &istream)
|
Variable Variable::fromSAS(utils::Parser &parser)
|
||||||
{
|
{
|
||||||
Variable variable;
|
Variable variable;
|
||||||
|
|
||||||
utils::parseExpected<std::string>(istream, "begin_variable");
|
parser.expect<std::string>("begin_variable");
|
||||||
|
|
||||||
variable.m_name = utils::parse<std::string>(istream);
|
variable.m_name = parser.parse<std::string>();
|
||||||
variable.m_axiomLayer = utils::parse<int>(istream);
|
variable.m_axiomLayer = parser.parse<int>();
|
||||||
|
|
||||||
const auto numberOfValues = utils::parse<size_t>(istream);
|
const auto numberOfValues = parser.parse<size_t>();
|
||||||
variable.m_values.reserve(numberOfValues);
|
variable.m_values.reserve(numberOfValues);
|
||||||
|
|
||||||
for (size_t j = 0; j < numberOfValues; j++)
|
for (size_t j = 0; j < numberOfValues; j++)
|
||||||
{
|
{
|
||||||
variable.m_values.emplace_back(Value::fromSAS(istream));
|
variable.m_values.emplace_back(Value::fromSAS(parser));
|
||||||
|
|
||||||
// <none of those> values are only allowed at the end
|
// <none of those> values are only allowed at the end
|
||||||
if (j < numberOfValues - 1 && variable.m_values[j] == Value::None)
|
if (j < numberOfValues - 1 && variable.m_values[j] == Value::None)
|
||||||
throw utils::ParserException("<none of those> value must be the last value of a variable");
|
throw utils::ParserException(parser, "<none of those> value must be the last value of a variable");
|
||||||
}
|
}
|
||||||
|
|
||||||
utils::parseExpected<std::string>(istream, "end_variable");
|
parser.expect<std::string>("end_variable");
|
||||||
|
|
||||||
return variable;
|
return variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Variable::printNameAsASPPredicate(std::ostream &ostream) const
|
void Variable::printNameAsASPPredicate(utils::LogStream &outputStream) const
|
||||||
{
|
{
|
||||||
ostream << "variable(" << utils::escapeASP(m_name) << ")";
|
outputStream << utils::Keyword("variable") << "(" << utils::escapeASP(m_name) << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
const Variable &Variable::referenceFromSAS(std::istream &istream, const Variables &variables)
|
const Variable &Variable::referenceFromSAS(utils::Parser &parser, const Variables &variables)
|
||||||
{
|
{
|
||||||
const auto variableID = utils::parse<size_t>(istream);
|
const auto variableID = parser.parse<size_t>();
|
||||||
|
|
||||||
if (variableID >= variables.size())
|
if (variableID >= variables.size())
|
||||||
throw utils::ParserException("Variable index out of range (index " + std::to_string(variableID) + ")");
|
throw utils::ParserException(parser, "variable index out of range (index " + std::to_string(variableID) + ")");
|
||||||
|
|
||||||
return variables[variableID];
|
return variables[variableID];
|
||||||
}
|
}
|
||||||
|
@@ -4,8 +4,6 @@
|
|||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
#include <plasp/utils/Parsing.h>
|
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
namespace sas
|
namespace sas
|
||||||
@@ -26,13 +24,13 @@ VariableTransition::VariableTransition()
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
VariableTransition VariableTransition::fromSAS(std::istream &istream, const Variables &variables)
|
VariableTransition VariableTransition::fromSAS(utils::Parser &parser, const Variables &variables)
|
||||||
{
|
{
|
||||||
VariableTransition variableTransition;
|
VariableTransition variableTransition;
|
||||||
|
|
||||||
variableTransition.m_variable = &Variable::referenceFromSAS(istream, variables);
|
variableTransition.m_variable = &Variable::referenceFromSAS(parser, variables);
|
||||||
variableTransition.m_valueBefore = &Value::referenceFromSAS(istream, *variableTransition.m_variable);
|
variableTransition.m_valueBefore = &Value::referenceFromSAS(parser, *variableTransition.m_variable);
|
||||||
variableTransition.m_valueAfter = &Value::referenceFromSAS(istream, *variableTransition.m_variable);
|
variableTransition.m_valueAfter = &Value::referenceFromSAS(parser, *variableTransition.m_variable);
|
||||||
|
|
||||||
return variableTransition;
|
return variableTransition;
|
||||||
}
|
}
|
||||||
|
145
src/plasp/utils/Logger.cpp
Normal file
145
src/plasp/utils/Logger.cpp
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
#include <plasp/utils/Logger.h>
|
||||||
|
|
||||||
|
#include <plasp/utils/Formatting.h>
|
||||||
|
|
||||||
|
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 Parser::Coordinate &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 Parser &parser, const std::string &message)
|
||||||
|
{
|
||||||
|
if (m_warningLevel == WarningLevel::Ignore)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_warningLevel == WarningLevel::Error)
|
||||||
|
throw ParserException(parser, message);
|
||||||
|
|
||||||
|
const auto coordinate = parser.coordinate();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
621
src/plasp/utils/Parser.cpp
Normal file
621
src/plasp/utils/Parser.cpp
Normal file
@@ -0,0 +1,621 @@
|
|||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
|
#include <plasp/utils/ParserException.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace utils
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Parser
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::istreambuf_iterator<char> Parser::EndOfFile = std::istreambuf_iterator<char>();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Parser::Parser()
|
||||||
|
: m_isCaseSensitive{true}
|
||||||
|
{
|
||||||
|
std::setlocale(LC_NUMERIC, "C");
|
||||||
|
|
||||||
|
// Don’t skip whitespace
|
||||||
|
m_stream.exceptions(std::istream::badbit);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Parser::Parser(std::string streamName, std::istream &istream)
|
||||||
|
: Parser()
|
||||||
|
{
|
||||||
|
readStream(streamName, istream);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Parser::Parser(Parser &&other)
|
||||||
|
: m_stream{std::move(other.m_stream)},
|
||||||
|
m_streamDelimiters{std::move(other.m_streamDelimiters)},
|
||||||
|
m_isCaseSensitive{other.m_isCaseSensitive}
|
||||||
|
{
|
||||||
|
other.m_isCaseSensitive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Parser &Parser::operator=(Parser &&other)
|
||||||
|
{
|
||||||
|
m_stream = std::move(other.m_stream);
|
||||||
|
m_streamDelimiters = std::move(other.m_streamDelimiters);
|
||||||
|
m_isCaseSensitive = other.m_isCaseSensitive;
|
||||||
|
|
||||||
|
other.m_isCaseSensitive = true;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Parser::readStream(std::string streamName, std::istream &istream)
|
||||||
|
{
|
||||||
|
// Store position of new section
|
||||||
|
const auto position = m_stream.tellp();
|
||||||
|
|
||||||
|
m_streamDelimiters.push_back({position, streamName});
|
||||||
|
|
||||||
|
m_stream << istream.rdbuf();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Parser::readFile(const boost::filesystem::path &path)
|
||||||
|
{
|
||||||
|
if (!boost::filesystem::is_regular_file(path))
|
||||||
|
throw std::runtime_error("File does not exist: “" + path.string() + "”");
|
||||||
|
|
||||||
|
std::ifstream fileStream(path.string(), std::ios::in);
|
||||||
|
|
||||||
|
readStream(path.string(), fileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Parser::reset()
|
||||||
|
{
|
||||||
|
m_stream.clear();
|
||||||
|
seek(std::ios::beg);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Parser::seek(Position position)
|
||||||
|
{
|
||||||
|
m_stream.clear();
|
||||||
|
m_stream.seekg(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Parser::Position Parser::position() const
|
||||||
|
{
|
||||||
|
return m_stream.tellg();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Parser::Coordinate Parser::coordinate() const
|
||||||
|
{
|
||||||
|
const auto currentPosition = position();
|
||||||
|
|
||||||
|
// Find current section
|
||||||
|
auto currentFile = std::find_if(m_streamDelimiters.crbegin(), m_streamDelimiters.crend(),
|
||||||
|
[&](const auto &fileDelimiter)
|
||||||
|
{
|
||||||
|
return currentPosition >= fileDelimiter.position;
|
||||||
|
});
|
||||||
|
|
||||||
|
// If the parser is at the end of the stream, still count from the beginning of the last section
|
||||||
|
if (currentFile == m_streamDelimiters.crend())
|
||||||
|
currentFile = m_streamDelimiters.crbegin();
|
||||||
|
|
||||||
|
// Go back to beginning of section
|
||||||
|
m_stream.clear();
|
||||||
|
m_stream.seekg(currentFile->position);
|
||||||
|
|
||||||
|
size_t row = 1;
|
||||||
|
size_t column = 1;
|
||||||
|
|
||||||
|
// Compute the coordinate character by character
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (currentPosition == -1 && atEndOfStream())
|
||||||
|
break;
|
||||||
|
else if (currentPosition >= 0 && position() >= currentPosition)
|
||||||
|
break;
|
||||||
|
|
||||||
|
const auto character = currentCharacter();
|
||||||
|
|
||||||
|
if (character == '\n')
|
||||||
|
{
|
||||||
|
row++;
|
||||||
|
column = 1;
|
||||||
|
}
|
||||||
|
else if (std::isblank(character) || std::isprint(character))
|
||||||
|
column++;
|
||||||
|
|
||||||
|
m_stream.ignore(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {currentFile->sectionName, row, column};
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Parser::setCaseSensitive(bool isCaseSensitive)
|
||||||
|
{
|
||||||
|
m_isCaseSensitive = isCaseSensitive;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
char Parser::currentCharacter() const
|
||||||
|
{
|
||||||
|
if (m_isCaseSensitive)
|
||||||
|
return m_stream.peek();
|
||||||
|
|
||||||
|
return std::tolower(m_stream.peek());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool Parser::atEndOfStream() const
|
||||||
|
{
|
||||||
|
return position() == -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Parser::checkStream() const
|
||||||
|
{
|
||||||
|
if (atEndOfStream())
|
||||||
|
throw ParserException(*this, "reading past end of file");
|
||||||
|
|
||||||
|
if (m_stream.fail())
|
||||||
|
throw ParserException(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Parser::advance()
|
||||||
|
{
|
||||||
|
checkStream();
|
||||||
|
m_stream.ignore(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Parser::skipWhiteSpace()
|
||||||
|
{
|
||||||
|
return skipWhiteSpace(
|
||||||
|
[](const auto character)
|
||||||
|
{
|
||||||
|
return std::isspace(character);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Parser::skipLine()
|
||||||
|
{
|
||||||
|
checkStream();
|
||||||
|
|
||||||
|
while (currentCharacter() != '\n')
|
||||||
|
advance();
|
||||||
|
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::string Parser::getLine()
|
||||||
|
{
|
||||||
|
checkStream();
|
||||||
|
|
||||||
|
std::string value;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
const auto character = currentCharacter();
|
||||||
|
|
||||||
|
advance();
|
||||||
|
|
||||||
|
if (character == '\n')
|
||||||
|
break;
|
||||||
|
else if (character == '\r')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
value.push_back(character);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
std::string Parser::parse<std::string>()
|
||||||
|
{
|
||||||
|
skipWhiteSpace();
|
||||||
|
|
||||||
|
std::string value;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
const auto character = currentCharacter();
|
||||||
|
|
||||||
|
if (std::isspace(character))
|
||||||
|
break;
|
||||||
|
|
||||||
|
value.push_back(character);
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
bool Parser::probe<std::string>(const std::string &expectedValue)
|
||||||
|
{
|
||||||
|
const auto previousPosition = position();
|
||||||
|
|
||||||
|
if (!std::iswspace(expectedValue.front()))
|
||||||
|
skipWhiteSpace();
|
||||||
|
|
||||||
|
const auto match = std::find_if(expectedValue.cbegin(), expectedValue.cend(),
|
||||||
|
[&](const auto &expectedCharacter)
|
||||||
|
{
|
||||||
|
const auto character = static_cast<char>(this->currentCharacter());
|
||||||
|
|
||||||
|
if (character != expectedCharacter)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
this->advance();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto differs = (match != expectedValue.cend());
|
||||||
|
|
||||||
|
if (!differs)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
seek(previousPosition);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void Parser::expect<std::string>(const std::string &expectedValue)
|
||||||
|
{
|
||||||
|
if (!probe<std::string>(expectedValue))
|
||||||
|
throw ParserException(*this, "expected “" + expectedValue + "”");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
char Parser::parse<char>()
|
||||||
|
{
|
||||||
|
const auto value = currentCharacter();
|
||||||
|
|
||||||
|
advance();
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
bool Parser::probe<char>(const char &expectedValue)
|
||||||
|
{
|
||||||
|
if (currentCharacter() != expectedValue)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
advance();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void Parser::expect<char>(const char &expectedValue)
|
||||||
|
{
|
||||||
|
if (!probe<char>(expectedValue))
|
||||||
|
throw ParserException(*this, std::string("expected “") + expectedValue + "”");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
uint64_t Parser::parseIntegerBody()
|
||||||
|
{
|
||||||
|
checkStream();
|
||||||
|
|
||||||
|
if (!std::isdigit(currentCharacter()))
|
||||||
|
throw ParserException(*this, "could not parse integer value");
|
||||||
|
|
||||||
|
uint64_t value = 0;
|
||||||
|
|
||||||
|
while (!atEndOfStream())
|
||||||
|
{
|
||||||
|
const auto character = currentCharacter();
|
||||||
|
|
||||||
|
if (!std::isdigit(character))
|
||||||
|
break;
|
||||||
|
|
||||||
|
value *= 10;
|
||||||
|
value += character - '0';
|
||||||
|
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
int64_t Parser::parse<int64_t>()
|
||||||
|
{
|
||||||
|
skipWhiteSpace();
|
||||||
|
|
||||||
|
bool positive = probe('+') || !probe('-');
|
||||||
|
|
||||||
|
const auto value = parseIntegerBody();
|
||||||
|
|
||||||
|
return (positive ? value : -value);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
uint64_t Parser::parse<uint64_t>()
|
||||||
|
{
|
||||||
|
skipWhiteSpace();
|
||||||
|
|
||||||
|
if (currentCharacter() == '-')
|
||||||
|
throw ParserException(*this, "expected unsigned integer, got signed one");
|
||||||
|
|
||||||
|
return parseIntegerBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
bool Parser::probe<int64_t>(const int64_t &expectedValue)
|
||||||
|
{
|
||||||
|
const auto previousPosition = position();
|
||||||
|
const auto value = parse<int64_t>();
|
||||||
|
|
||||||
|
if (value == expectedValue)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
seek(previousPosition);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
bool Parser::probe<uint64_t>(const uint64_t &expectedValue)
|
||||||
|
{
|
||||||
|
const auto previousPosition = position();
|
||||||
|
const auto value = parse<uint64_t>();
|
||||||
|
|
||||||
|
if (value == expectedValue)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
seek(previousPosition);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void Parser::expect<int64_t>(const int64_t &expectedValue)
|
||||||
|
{
|
||||||
|
if (!probe<int64_t>(expectedValue))
|
||||||
|
throw ParserException(*this, "expected “" + std::to_string(expectedValue) + "”");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void Parser::expect<uint64_t>(const uint64_t &expectedValue)
|
||||||
|
{
|
||||||
|
if (!probe<uint64_t>(expectedValue))
|
||||||
|
throw ParserException(*this, "expected “" + std::to_string(expectedValue) + "”");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
int32_t Parser::parse<int32_t>()
|
||||||
|
{
|
||||||
|
return static_cast<int32_t>(parse<int64_t>());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
uint32_t Parser::parse<uint32_t>()
|
||||||
|
{
|
||||||
|
return static_cast<uint32_t>(parse<uint64_t>());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
bool Parser::probe<int32_t>(const int32_t &expectedValue)
|
||||||
|
{
|
||||||
|
return probe<int64_t>(static_cast<int64_t>(expectedValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
bool Parser::probe<uint32_t>(const uint32_t &expectedValue)
|
||||||
|
{
|
||||||
|
return probe<uint64_t>(static_cast<uint64_t>(expectedValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void Parser::expect<int32_t>(const int32_t &expectedValue)
|
||||||
|
{
|
||||||
|
expect<int64_t>(static_cast<int64_t>(expectedValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void Parser::expect<uint32_t>(const uint32_t &expectedValue)
|
||||||
|
{
|
||||||
|
expect<uint64_t>(static_cast<uint64_t>(expectedValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
bool Parser::parse<bool>()
|
||||||
|
{
|
||||||
|
skipWhiteSpace();
|
||||||
|
|
||||||
|
if (probe('0'))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (probe('1'))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
throw ParserException(*this, "could not parse Boolean value");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void Parser::expect<bool>(const bool &expectedValue)
|
||||||
|
{
|
||||||
|
const auto value = parse<bool>();
|
||||||
|
|
||||||
|
if (value != expectedValue)
|
||||||
|
throw ParserException(*this, "expected “" + std::to_string(expectedValue) + "”");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool Parser::probeNumber()
|
||||||
|
{
|
||||||
|
const auto previousPosition = position();
|
||||||
|
|
||||||
|
skipWhiteSpace();
|
||||||
|
|
||||||
|
while (!std::iswspace(currentCharacter()))
|
||||||
|
if (!std::isdigit(currentCharacter()))
|
||||||
|
{
|
||||||
|
seek(previousPosition);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Parser::removeComments(const std::string &startSequence, const std::string &endSequence, bool removeEnd)
|
||||||
|
{
|
||||||
|
const auto inPosition = m_stream.tellg();
|
||||||
|
const auto outPosition = m_stream.tellp();
|
||||||
|
|
||||||
|
m_stream.seekg(0);
|
||||||
|
|
||||||
|
const auto removeRange =
|
||||||
|
[&](const auto &start, const auto &end)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(start != -1);
|
||||||
|
|
||||||
|
m_stream.clear();
|
||||||
|
m_stream.seekp(start);
|
||||||
|
m_stream.seekg(start);
|
||||||
|
|
||||||
|
auto position = start;
|
||||||
|
|
||||||
|
while (end == -1 || position < end)
|
||||||
|
{
|
||||||
|
m_stream.ignore(1);
|
||||||
|
|
||||||
|
if (atEndOfStream())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_stream.put(' ');
|
||||||
|
position += static_cast<std::streamoff>(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
while (!atEndOfStream())
|
||||||
|
{
|
||||||
|
Position startPosition = m_stream.tellg();
|
||||||
|
|
||||||
|
while (!atEndOfStream())
|
||||||
|
{
|
||||||
|
startPosition = m_stream.tellg();
|
||||||
|
|
||||||
|
if (probe(startSequence))
|
||||||
|
break;
|
||||||
|
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
Position endPosition = m_stream.tellg();
|
||||||
|
|
||||||
|
while (!atEndOfStream())
|
||||||
|
{
|
||||||
|
endPosition = m_stream.tellg();
|
||||||
|
|
||||||
|
if (probe(endSequence))
|
||||||
|
break;
|
||||||
|
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (removeEnd)
|
||||||
|
endPosition = m_stream.tellg();
|
||||||
|
|
||||||
|
removeRange(startPosition, endPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_stream.clear();
|
||||||
|
|
||||||
|
m_stream.seekg(inPosition);
|
||||||
|
m_stream.seekp(outPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user