Compare commits
331 Commits
v3.0.0
...
v3.0.2-rc.
Author | SHA1 | Date | |
---|---|---|---|
4a2882711d | |||
08113c961a | |||
e2da46e20a | |||
0cf44da917 | |||
d03638919a | |||
f5d342a442 | |||
06cab2f098 | |||
9d67ae800d | |||
d2a1030320 | |||
5c17d23606 | |||
bc1759aedf | |||
b9aef10db3 | |||
bdb6ac9fba | |||
4d5f935e82 | |||
d604e44dff | |||
2c37da4cb4 | |||
741078c4fd | |||
e101cf2aab | |||
3dfae74468 | |||
2363f42bc9 | |||
491454ca3c | |||
562b2296e5 | |||
3535afb1e1 | |||
7a63e4abb9 | |||
2281cd1cd4 | |||
4037b339e4 | |||
00c3140f3b | |||
0fb282d153 | |||
7a73f99581 | |||
bdd68f04e1 | |||
a5a300b150 | |||
197cec923e | |||
c391a1f566 | |||
1727113a8b | |||
18ac959970 | |||
d00c5bb753 | |||
ffcf07b935 | |||
042531abc3 | |||
4fc7355fba | |||
c12be088c6 | |||
9c3cfe8f7b | |||
d4c168af30 | |||
f2d3aee662 | |||
340db244f6 | |||
8969364f73 | |||
b67168134b | |||
97d33da686 | |||
1f35bda3d2 | |||
6960e8a8c7 | |||
b30cecd297 | |||
99fc6988a3 | |||
cf022f9959 | |||
0a1044743e | |||
94b204615b | |||
230c6dfc15 | |||
8be67e7065 | |||
378b2ae673 | |||
36e517bd80 | |||
569b3d0c97 | |||
daf68d24ab | |||
8a82f52100 | |||
d0864b9efe | |||
18bd606262 | |||
252f50108b | |||
015c34fc2b | |||
d7b47797df | |||
544d4e0635 | |||
73c9d6c1f3 | |||
d9578b6f1c | |||
b5e325cbee | |||
234938349c | |||
9ed7277ec9 | |||
dc87c09442 | |||
00688765fd | |||
3702b72feb | |||
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
|
||||||
|
36
CHANGELOG.md
Normal file
36
CHANGELOG.md
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# Change Log
|
||||||
|
|
||||||
|
## (unreleased)
|
||||||
|
|
||||||
|
Features:
|
||||||
|
|
||||||
|
* unified translation format for SAS and PDDL files
|
||||||
|
* documentation of `plasp`’s output format
|
||||||
|
|
||||||
|
Bug Fixes:
|
||||||
|
|
||||||
|
* fixes minor formatting issues in SAS translation
|
||||||
|
|
||||||
|
## 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,50 +1,70 @@
|
|||||||
# 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` translates planning problem instances to ASP facts.
|
||||||
|
`plasp` 3 supports the input languages [PDDL 3.1](https://helios.hud.ac.uk/scommv/IPC-14/software.html) (only basic features currently) and [SAS](http://www.fast-downward.org/TranslatorOutputFormat) (full support of SAS 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 problem.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]
|
||||||
|
```
|
||||||
|
|
||||||
|
`plasp` automatically detects the language of the input program.
|
||||||
|
|
||||||
|
See [command-line interface](doc/command-line-interface.md) for more detail.
|
||||||
|
|
||||||
|
## Output Format
|
||||||
|
|
||||||
|
`plasp` provides a uniform output format for SAS and PDDL input problems.
|
||||||
|
|
||||||
|
See [output format](doc/output-format.md) for more detail.
|
||||||
|
|
||||||
|
If you want to write your own meta encoding for `plasp`’s output, this [simple example encoding](encodings/sequential-incremental.lp) gets you started.
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
`plasp` requires a C++14 compiler (preferrably GCC ≥ 6.1), the `boost` libraries (≥ 1.55), and CMake for building.
|
`plasp` requires `boost` and is built via CMake and a C++ compiler.
|
||||||
|
|
||||||
```bash
|
See [building instructions](doc/building-instructions.md) for more detail.
|
||||||
$ git clone https://github.com/potassco/plasp.git
|
|
||||||
$ cd plasp
|
|
||||||
$ mkdir -p build/release
|
|
||||||
$ cd build/release
|
|
||||||
$ cmake ../.. -DCMAKE_BUILD_TYPE=Release
|
|
||||||
$ make
|
|
||||||
```
|
|
||||||
|
|
||||||
The built `plasp` binary is then located at `plasp/build/release/bin/plasp`.
|
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
|
|
||||||
@@ -52,5 +72,5 @@ The built `plasp` binary is then located at `plasp/build/release/bin/plasp`.
|
|||||||
|
|
||||||
### 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,108 @@ 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.2-rc.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<plasp::utils::CaseInsensitiveParserPolicy> parser;
|
||||||
const auto sasTranslator = plasp::sas::TranslatorASP(sasDescription);
|
|
||||||
sasTranslator.translate(std::cout);
|
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.read(inputFile);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
parser.read("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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
40
doc/building-instructions.md
Normal file
40
doc/building-instructions.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Building Instructions
|
||||||
|
|
||||||
|
`plasp` requires a C++14 compiler (preferrably GCC ≥ 6.1 or clang ≥ 3.8), the `boost` libraries (≥ 1.55), and CMake for building.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ git clone https://github.com/potassco/plasp.git
|
||||||
|
$ cd plasp
|
||||||
|
$ mkdir -p build/release
|
||||||
|
$ cd build/release
|
||||||
|
$ cmake ../.. -DCMAKE_BUILD_TYPE=Release
|
||||||
|
$ make
|
||||||
|
```
|
||||||
|
|
||||||
|
The built `plasp` binary is then located at `plasp/build/release/bin/plasp`.
|
||||||
|
|
||||||
|
To update `plasp` to the most recent version, perform the following steps:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ cd plasp
|
||||||
|
$ git pull
|
||||||
|
$ cd build/release
|
||||||
|
$ cmake .
|
||||||
|
$ make
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running the Tests
|
||||||
|
|
||||||
|
`plasp` provides unit tests written using the [Google Test](https://github.com/google/googletest) framework.
|
||||||
|
Before building and running the tests, make sure you have fetched the Google Test git submodule:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ git submodule init
|
||||||
|
$ git submodule update
|
||||||
|
```
|
||||||
|
|
||||||
|
Afterward, build and run the tests as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ make run-tests
|
||||||
|
```
|
18
doc/command-line-interface.md
Normal file
18
doc/command-line-interface.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Command-Line Interface
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ plasp [files] [options]
|
||||||
|
```
|
||||||
|
|
||||||
|
`plasp` automatically detects the language of the input files.
|
||||||
|
|
||||||
|
Multiple files may be provided in an arbitrary order.
|
||||||
|
`[files]` may also be omitted, in which case the input is read from `std::cin`.
|
||||||
|
|
||||||
|
`plasp` supports the following options:
|
||||||
|
|
||||||
|
| **option** | **explanation** |
|
||||||
|
|-----------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|
|
||||||
|
| `-l` [ `--language` ] | Specify the input language (`sas` or `pddl`). Omit for automatic detection. |
|
||||||
|
| `--warning-level` arg (=`normal`) | Specify whether to output warnings normally (`normal`), to treat them as critical errors (`error`), or to ignore them (`ignore`). |
|
||||||
|
| `--color` arg (=`auto`) | Specify whether to colorize the output (`always`, `never`, or `auto`). |
|
22
doc/feature-requirements.md
Normal file
22
doc/feature-requirements.md
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Feature Requirements
|
||||||
|
|
||||||
|
Feature requirements are part of `plasp`’s [output format](output-format.md).
|
||||||
|
Currently, `plasp` detects feature requirements only for SAS problems.
|
||||||
|
|
||||||
|
`plasp` supports the following feature requirements:
|
||||||
|
|
||||||
|
SAS feature | description
|
||||||
|
------------|------------
|
||||||
|
`actionCosts` | actions have associated costs (see [action costs](output-format.md#action-costs))
|
||||||
|
`axiomRules` | immediate actions are used, which are executed as soon as the preconditions are satisfied (see [axiom rules](output-format.md#axiom-rules))
|
||||||
|
`conditionalEffects` | some effects of an action may have additional conditions (see [actions](output-format.md#actions))
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
The following specifies that the input problem has the two requirements `actionCosts` and `conditionalEffects`.
|
||||||
|
|
||||||
|
```prolog
|
||||||
|
% requirements
|
||||||
|
requiresFeature(actionCosts).
|
||||||
|
requiresFeature(conditionalEffects).
|
||||||
|
```
|
202
doc/output-format.md
Normal file
202
doc/output-format.md
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
# Output Format
|
||||||
|
|
||||||
|
`plasp` 3 translates SAS and PDDL files into a uniform ASP fact format.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Essentially, `plasp`’s output format consists of [state variables](#variables) that are modified by [actions](#actions) if their preconditions are fulfilled.
|
||||||
|
Variables reference [entities](#constants-objects) that are affected by the actions.
|
||||||
|
As with PDDL, the objective is to achieve a specific [goal](#goal) starting from an [initial state](#initial-state) by executing a sequence of actions.
|
||||||
|
|
||||||
|
`plasp`’s variables correspond to the multivalued variables in SAS.
|
||||||
|
PDDL predicates are turned into Boolean variables to make the output format consistent.
|
||||||
|
|
||||||
|
Actions are modeled exactly as PDDL actions and SAS operators.
|
||||||
|
|
||||||
|
## In a Nutshell
|
||||||
|
|
||||||
|
The following illustrates `plasp`’s output format for the problem of turning switches on and off.
|
||||||
|
|
||||||
|
```prolog
|
||||||
|
% declares the type "type(switch)"
|
||||||
|
type(type(switch)).
|
||||||
|
|
||||||
|
% introduces a switch "constant(a)"
|
||||||
|
constant(constant(a)).
|
||||||
|
has(constant(a), type(switch)).
|
||||||
|
|
||||||
|
% declares a variable "variable(on(X))" for switches X
|
||||||
|
variable(variable(on(X))) :- has(X, type(switch)).
|
||||||
|
|
||||||
|
% the variable may be true or false
|
||||||
|
contains(variable(on(X)), value(on(X)), true)) :- has(X, type(switch)).
|
||||||
|
contains(variable(on(X)), value(on(X)), false)) :- has(X, type(switch)).
|
||||||
|
|
||||||
|
% declares the action "action(turnOn(X))", which requires switch X to be off and then turns it on
|
||||||
|
action(action(turnOn(X))) :- has(X, type(switch)).
|
||||||
|
precondition(action(turnOn(X)), variable(on(X)), value(on(X), false)) :- has(X, type(switch)).
|
||||||
|
postcondition(action(turnOn(X)), effect(0), variable(on(X)), value(on(X), true)) :- has(X, type(switch)).
|
||||||
|
|
||||||
|
% initially, the switch is off
|
||||||
|
initialState(variable(on(constant(a))), value(on(constant(a)), false)).
|
||||||
|
|
||||||
|
% in the end, the switch should be on
|
||||||
|
goal(variable(on(constant(a))), value(on(constant(a)), true)).
|
||||||
|
```
|
||||||
|
|
||||||
|
## Syntax and Semantics
|
||||||
|
|
||||||
|
`plasp` structures the translated ASP facts into multiple sections, which are explained in the following.
|
||||||
|
|
||||||
|
### Feature Requirements
|
||||||
|
|
||||||
|
```prolog
|
||||||
|
% declares a required feature
|
||||||
|
requires(feature(<name>)).
|
||||||
|
```
|
||||||
|
|
||||||
|
`plasp` recognizes and declares advanced features used by the input problem, such as conditional effects, [mutex groups](#mutex-groups) and [axiom rules](#axiom-rules) (currently only SAS).
|
||||||
|
See the [full list of supported features](feature-requirements.md) for more information.
|
||||||
|
|
||||||
|
The feature requirement predicates may be used in meta encodings to warn about unsupported features.
|
||||||
|
|
||||||
|
### Types
|
||||||
|
|
||||||
|
```prolog
|
||||||
|
% declares a <type>
|
||||||
|
type(type(<name>)).
|
||||||
|
|
||||||
|
% specifies <constant> to be of type type(<name>)
|
||||||
|
has(<constant>, type(<name>)).
|
||||||
|
```
|
||||||
|
|
||||||
|
[Variables](#variables), [constants](#constants-objects), and [objects](#constants-objects) may be typed. Types are only available with PDDL and if typing is enabled.
|
||||||
|
|
||||||
|
### Variables
|
||||||
|
|
||||||
|
```prolog
|
||||||
|
% declares a <variable>
|
||||||
|
variable(variable(<name>)).
|
||||||
|
|
||||||
|
% adds a <value> to the domain of a <variable>
|
||||||
|
contains(<variable>, <value>).
|
||||||
|
```
|
||||||
|
|
||||||
|
`plasp`’s variables represent the current state of the planning problem.
|
||||||
|
Variables are linked to the problem's [objects](#constants-objects) and [constants](#constants-objects).
|
||||||
|
|
||||||
|
`plasp`’s variables are multivalued, and each variable has exactly one value at each point in time.
|
||||||
|
|
||||||
|
With SAS, variable names are numbers starting at 0, `variable(<number>)`.
|
||||||
|
SAS variables are inherently multivalued, which results in two or more values of the form `value(<SAS predicate>, <bool>)` for each variable.
|
||||||
|
|
||||||
|
With PDDL, Boolean variables are created from the PDDL predicates.
|
||||||
|
Variables ared named after the PDDL predicates, `variable(<PDDL predicate>).`
|
||||||
|
Each variable contains exactly two values (one `true`, one `false`) of the form `value(<PDDL predicate>, <bool>)`.
|
||||||
|
Note that with PDDL, variables and values are named identically.
|
||||||
|
|
||||||
|
### Actions
|
||||||
|
|
||||||
|
```prolog
|
||||||
|
% declares an <action>
|
||||||
|
action(action(<name>)).
|
||||||
|
|
||||||
|
% defines that as a precondition to <action>, <variable> must have value <value>
|
||||||
|
precondition(<action>, <variable>, <value>).
|
||||||
|
|
||||||
|
% defines that after applying <action>, <variable> is assigned <value>
|
||||||
|
postcondition(<action>, effect(<number>), <variable>, <value>).
|
||||||
|
|
||||||
|
% defines the condition of a conditional effect
|
||||||
|
precondition(effect(<number>), <variable>, <value>).
|
||||||
|
|
||||||
|
% specifies the costs of applying <action>
|
||||||
|
costs(<action>, <number>).
|
||||||
|
```
|
||||||
|
|
||||||
|
Actions may require certain variables to have specific values in order to be executed.
|
||||||
|
After applying an action, variables get new values according to the action's postconditions.
|
||||||
|
|
||||||
|
Actions may have *conditional effects*, that is, certain postconditions are only applied if additional conditions are satisfied.
|
||||||
|
For this reason, each conditional effect is uniquely identified with a predicate `effect(<number>)` as the second argument of the `postcondition` facts.
|
||||||
|
The conditions of conditional effects are given by additional `precondition` facts that take the respective `effect(<number>)` predicates as the first argument.
|
||||||
|
|
||||||
|
Unconditional effects are identified with `effect(unconditional)`.
|
||||||
|
|
||||||
|
Conditional effects are currently only supported with SAS input problems.
|
||||||
|
|
||||||
|
Actions may also have *action costs* required to apply them. Action costs are currently supported for SAS only.
|
||||||
|
|
||||||
|
### Constants/Objects
|
||||||
|
|
||||||
|
```prolog
|
||||||
|
% declares a <constant> or object
|
||||||
|
constant(constant(<name>)).
|
||||||
|
|
||||||
|
% specifies <constant> to be of type type(<name>)
|
||||||
|
has(<constant>, <type>).
|
||||||
|
```
|
||||||
|
|
||||||
|
Constants and objects are the entities that are affected by [actions](#actions), for instance, the blocks in a Blocks World problem.
|
||||||
|
Constants are global for a domain, while objects are problem-specific.
|
||||||
|
|
||||||
|
`plasp` does not distinguish between the two (modeling both as constants), as both are identically used static identifiers.
|
||||||
|
|
||||||
|
### Initial State
|
||||||
|
|
||||||
|
```prolog
|
||||||
|
% initializes <variable> with a specific <value>
|
||||||
|
initialState(<variable>, <value>).
|
||||||
|
```
|
||||||
|
|
||||||
|
The initial state contains all [variable](#variables) assignments that hold before executing any [actions](#actions).
|
||||||
|
|
||||||
|
Note that with PDDL, the initial state might not assign values to all variables. Instead, unassigned values have to be assigned `false` manually.
|
||||||
|
|
||||||
|
### Goal
|
||||||
|
|
||||||
|
```prolog
|
||||||
|
% specifies that <variable> shall obtain <value> in the end
|
||||||
|
goal(<variable>, <value>).
|
||||||
|
```
|
||||||
|
|
||||||
|
The goal specifies all variable assignments that have to be fulfilled after executing the plan.
|
||||||
|
|
||||||
|
### Mutex Groups
|
||||||
|
|
||||||
|
```prolog
|
||||||
|
% declares a <mutex group>
|
||||||
|
mutexGroup(mutexGroup(<number>)).
|
||||||
|
|
||||||
|
% adds the assignment of <variable> to <value> to a <mutex group>
|
||||||
|
contains(<mutex group>, <variable>, <value>).
|
||||||
|
```
|
||||||
|
|
||||||
|
SAS contains information about mutually exclusive [variable](#variables) assignments.
|
||||||
|
That is, *at most one* variable assignment of each mutex group must be satisfied at all times.
|
||||||
|
|
||||||
|
Mutex group facts are only present with SAS input programs and not PDDL.
|
||||||
|
|
||||||
|
Mutex groups contain essential information in order to find plans correctly.
|
||||||
|
That is, if mutex groups are present in `plasp`’s output, they have to be accounted for appropriately.
|
||||||
|
|
||||||
|
### Axiom Rules
|
||||||
|
|
||||||
|
```prolog
|
||||||
|
% declares an <axiom rule>
|
||||||
|
axiomRule(axiomRule(<number>)).
|
||||||
|
|
||||||
|
% defines that as a precondition to <axiom rule>, <variable> must have value <value>
|
||||||
|
precondition(<axiom rule>, <variable>, <value>).
|
||||||
|
|
||||||
|
% defines that after applying <axiom rule>, <variable> is assigned <value>
|
||||||
|
postcondition(<axiom rule>, <variable>, <value>).
|
||||||
|
```
|
||||||
|
|
||||||
|
Axiom rules are similar to [actions](#actions) in that they modify [variables](#variables) if certain preconditions are satisfied.
|
||||||
|
However, axiom rules must be applied *immediately* as soon as their preconditions are satisfied.
|
||||||
|
|
||||||
|
Axiom rule facts are only present with SAS input programs and not PDDL.
|
||||||
|
|
||||||
|
Axiom rules contain essential information in order to find plans correctly.
|
||||||
|
That is, if axiom rules are present in `plasp`’s output, they have to be accounted for appropriately.
|
@@ -1,40 +0,0 @@
|
|||||||
#include <incmode>.
|
|
||||||
|
|
||||||
% Check feature requirements
|
|
||||||
:- requiresFeature(actionCosts).
|
|
||||||
:- requiresFeature(axiomRules).
|
|
||||||
:- requiresFeature(conditionalEffects).
|
|
||||||
|
|
||||||
#program base.
|
|
||||||
|
|
||||||
% Establish initial state
|
|
||||||
holds(Var, Val, 0) :- initialState(Var, Val).
|
|
||||||
|
|
||||||
#program step(t).
|
|
||||||
|
|
||||||
% Perform actions
|
|
||||||
1 {occurs(action(A), t) : action(A)} 1.
|
|
||||||
|
|
||||||
% Check preconditions
|
|
||||||
:- occurs(A, t), precondition(A, Var, Val), not holds(Var, Val, t - 1).
|
|
||||||
|
|
||||||
% Apply effects
|
|
||||||
caused(Var, Val, t) :- occurs(A, t), postcondition(A, _, Var, Val).
|
|
||||||
modified(Var, t) :- caused(Var, Val, t).
|
|
||||||
|
|
||||||
holds(Var, Val, t) :- caused(Var, Val, t).
|
|
||||||
holds(Var, Val, t) :- holds(Var, Val, t - 1), not modified(Var, t).
|
|
||||||
|
|
||||||
% Check that variables have unique values
|
|
||||||
:- variable(X), Var = variable(X), not 1 {holds(Var, Val, t) : contains(Var, Val)} 1.
|
|
||||||
|
|
||||||
% Check mutexes
|
|
||||||
:- mutexGroup(X), M = mutexGroup(X), not {holds(Var, Val, t) : contains(M, Var, Val)} 1.
|
|
||||||
|
|
||||||
#program check(t).
|
|
||||||
|
|
||||||
% Verify that goal is met
|
|
||||||
:- query(t), goal(Var, Val), not holds(Var, Val, t).
|
|
||||||
|
|
||||||
#show query/1.
|
|
||||||
#show occurs/2.
|
|
43
encodings/sequential-incremental.lp
Normal file
43
encodings/sequential-incremental.lp
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#include <incmode>.
|
||||||
|
|
||||||
|
% Check feature requirements
|
||||||
|
:- requiresFeature(actionCosts).
|
||||||
|
:- requiresFeature(axiomRules).
|
||||||
|
:- requiresFeature(conditionalEffects).
|
||||||
|
|
||||||
|
#program base.
|
||||||
|
|
||||||
|
% Establish initial state
|
||||||
|
holds(Variable, Value, 0) :- initialState(Variable, Value).
|
||||||
|
|
||||||
|
% Make unspecified initial state variables false by default (for PDDL)
|
||||||
|
holds(variable(Variable), value(Variable, false), 0) :- variable(variable(Variable)), {initialState(variable(Variable), _)} 0.
|
||||||
|
|
||||||
|
#program step(t).
|
||||||
|
|
||||||
|
% Perform actions
|
||||||
|
1 {occurs(Action, t) : action(Action)} 1.
|
||||||
|
|
||||||
|
% Check preconditions
|
||||||
|
:- occurs(Action, t), precondition(Action, Variable, Value), not holds(Variable, Value, t - 1).
|
||||||
|
|
||||||
|
% Apply effects
|
||||||
|
caused(Variable, Value, t) :- occurs(Action, t), postcondition(Action, _, Variable, Value).
|
||||||
|
modified(Variable, t) :- caused(Variable, Value, t).
|
||||||
|
|
||||||
|
holds(Variable, Value, t) :- caused(Variable, Value, t).
|
||||||
|
holds(Variable, Value, t) :- holds(Variable, Value, t - 1), not modified(Variable, t).
|
||||||
|
|
||||||
|
% Check that variables have unique values
|
||||||
|
:- variable(Variable), not 1 {holds(Variable, Value, t) : contains(Variable, Value)} 1.
|
||||||
|
|
||||||
|
% Check mutexes
|
||||||
|
:- mutexGroup(MutexGroup), not {holds(Variable, Value, t) : contains(MutexGroup, Variable, Value)} 1.
|
||||||
|
|
||||||
|
#program check(t).
|
||||||
|
|
||||||
|
% Verify that goal is met
|
||||||
|
:- query(t), goal(Variable, Value), not holds(Variable, Value, 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
|
49
include/plasp/LanguageDetection.h
Normal file
49
include/plasp/LanguageDetection.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#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<utils::CaseInsensitiveParserPolicy> &parser)
|
||||||
|
{
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
// SAS begins with "begin_version"
|
||||||
|
if (parser.testAndSkip<std::string>("begin"))
|
||||||
|
{
|
||||||
|
parser.seek(0);
|
||||||
|
return Language::Type::SAS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip potential PDDL comments
|
||||||
|
while (parser.currentCharacter() == ';')
|
||||||
|
{
|
||||||
|
parser.skipLine();
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// PDDL contains sections starting with "(define"
|
||||||
|
if (parser.testAndSkip<std::string>("(") && parser.testAndSkip<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
|
70
include/plasp/pddl/Context.h
Normal file
70
include/plasp/pddl/Context.h
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
#ifndef __PLASP__PDDL__CONTEXT_H
|
||||||
|
#define __PLASP__PDDL__CONTEXT_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Parser.h>
|
||||||
|
#include <plasp/utils/Logger.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Context
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Context() = default;
|
||||||
|
~Context() = default;
|
||||||
|
|
||||||
|
explicit Context(Parser &&otherParser)
|
||||||
|
: parser{std::move(otherParser)}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit Context(utils::Logger &&otherLogger)
|
||||||
|
: logger{std::move(otherLogger)}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit Context(Parser &&otherParser, utils::Logger &&otherLogger)
|
||||||
|
: parser{std::move(otherParser)},
|
||||||
|
logger{std::move(otherLogger)}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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::Stream::Position m_domainPosition;
|
||||||
|
std::unique_ptr<Domain> m_domain;
|
||||||
|
utils::Stream::Position m_problemPosition;
|
||||||
|
std::unique_ptr<Problem> m_problem;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
93
include/plasp/pddl/Domain.h
Normal file
93
include/plasp/pddl/Domain.h
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
#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/Parser.h>
|
||||||
|
#include <plasp/pddl/Requirement.h>
|
||||||
|
#include <plasp/pddl/expressions/Constant.h>
|
||||||
|
#include <plasp/pddl/expressions/PredicateDeclaration.h>
|
||||||
|
#include <plasp/pddl/expressions/PrimitiveType.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::Stream::Position m_requirementsPosition;
|
||||||
|
Requirements m_requirements;
|
||||||
|
|
||||||
|
utils::Stream::Position m_typesPosition;
|
||||||
|
expressions::PrimitiveTypes m_types;
|
||||||
|
|
||||||
|
utils::Stream::Position m_constantsPosition;
|
||||||
|
expressions::Constants m_constants;
|
||||||
|
|
||||||
|
utils::Stream::Position m_predicatesPosition;
|
||||||
|
expressions::PredicateDeclarations m_predicates;
|
||||||
|
|
||||||
|
std::vector<utils::Stream::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/pddl/Parser.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// IO
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
inline void skipSection(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
|
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
|
49
include/plasp/pddl/Parser.h
Normal file
49
include/plasp/pddl/Parser.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#ifndef __PLASP__PDDL__PARSER_H
|
||||||
|
#define __PLASP__PDDL__PARSER_H
|
||||||
|
|
||||||
|
#include <plasp/utils/Parser.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Parser
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class PDDLParserPolicy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static char transformCharacter(char c) noexcept
|
||||||
|
{
|
||||||
|
return std::tolower(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isWhiteSpaceCharacter(char c)
|
||||||
|
{
|
||||||
|
return std::iswspace(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isIdentifierCharacter(char c)
|
||||||
|
{
|
||||||
|
return c != '?'
|
||||||
|
&& c != '('
|
||||||
|
&& c != ')'
|
||||||
|
&& c != ';'
|
||||||
|
&& std::isgraph(c);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
using Parser = utils::Parser<PDDLParserPolicy>;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
85
include/plasp/pddl/Problem.h
Normal file
85
include/plasp/pddl/Problem.h
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
#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/Parser.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::Stream::Position m_domainPosition;
|
||||||
|
|
||||||
|
utils::Stream::Position m_requirementsPosition;
|
||||||
|
Requirements m_requirements;
|
||||||
|
|
||||||
|
utils::Stream::Position m_objectsPosition;
|
||||||
|
expressions::Constants m_objects;
|
||||||
|
|
||||||
|
utils::Stream::Position m_initialStatePosition;
|
||||||
|
std::unique_ptr<InitialState> m_initialState;
|
||||||
|
|
||||||
|
utils::Stream::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
|
105
include/plasp/pddl/expressions/At.h
Normal file
105
include/plasp/pddl/expressions/At.h
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
#ifndef __PLASP__PDDL__EXPRESSIONS__AT_H
|
||||||
|
#define __PLASP__PDDL__EXPRESSIONS__AT_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/Expression.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.testAndSkip<std::string>("(")
|
||||||
|
|| !parser.testIdentifierAndSkip("at"))
|
||||||
|
{
|
||||||
|
parser.seek(position);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t timePoint;
|
||||||
|
|
||||||
|
const auto timePointPosition = parser.position();
|
||||||
|
|
||||||
|
if (parser.testIdentifierAndSkip("start"))
|
||||||
|
timePoint = TimePointStart;
|
||||||
|
else if (parser.testIdentifierAndSkip("end"))
|
||||||
|
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
|
111
include/plasp/pddl/expressions/Binary.h
Normal file
111
include/plasp/pddl/expressions/Binary.h
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
#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/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.testAndSkip<std::string>("(")
|
||||||
|
|| !parser.testIdentifierAndSkip(Derived::Identifier))
|
||||||
|
{
|
||||||
|
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
|
64
include/plasp/pddl/expressions/Constant.h
Normal file
64
include/plasp/pddl/expressions/Constant.h
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#ifndef __PLASP__PDDL__EXPRESSIONS__CONSTANT_H
|
||||||
|
#define __PLASP__PDDL__EXPRESSIONS__CONSTANT_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/Expression.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
|
117
include/plasp/pddl/expressions/NAry.h
Normal file
117
include/plasp/pddl/expressions/NAry.h
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
#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/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.testAndSkip<std::string>("(")
|
||||||
|
|| !parser.testIdentifierAndSkip(Derived::Identifier))
|
||||||
|
{
|
||||||
|
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(parser.coordinate(), "“" + 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
|
77
include/plasp/pddl/expressions/Not.h
Normal file
77
include/plasp/pddl/expressions/Not.h
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
#ifndef __PLASP__PDDL__EXPRESSIONS__NOT_H
|
||||||
|
#define __PLASP__PDDL__EXPRESSIONS__NOT_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/Expression.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.testAndSkip<std::string>("(")
|
||||||
|
|| !parser.testIdentifierAndSkip("not"))
|
||||||
|
{
|
||||||
|
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
|
55
include/plasp/pddl/expressions/PrimitiveType.h
Normal file
55
include/plasp/pddl/expressions/PrimitiveType.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#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/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);
|
||||||
|
|
||||||
@@ -43,17 +45,21 @@ class Description
|
|||||||
bool usesAxiomRules() const;
|
bool usesAxiomRules() const;
|
||||||
bool usesConditionalEffects() const;
|
bool usesConditionalEffects() const;
|
||||||
|
|
||||||
|
bool hasRequirements() const;
|
||||||
|
|
||||||
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/ParserException.h>
|
||||||
|
#include <plasp/utils/StreamCoordinate.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 StreamCoordinate &coordinate, const std::string &message);
|
||||||
|
void logWarning(const StreamCoordinate &parserCoordinate, const std::string &message);
|
||||||
|
|
||||||
|
private:
|
||||||
|
LogStream m_outputStream;
|
||||||
|
LogStream m_errorStream;
|
||||||
|
|
||||||
|
WarningLevel m_warningLevel;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
559
include/plasp/utils/Parser.h
Normal file
559
include/plasp/utils/Parser.h
Normal file
@@ -0,0 +1,559 @@
|
|||||||
|
#ifndef __PLASP__UTILS__PARSER_H
|
||||||
|
#define __PLASP__UTILS__PARSER_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <iterator>
|
||||||
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
#include <plasp/utils/ParserException.h>
|
||||||
|
#include <plasp/utils/ParserPolicy.h>
|
||||||
|
#include <plasp/utils/Stream.h>
|
||||||
|
#include <plasp/utils/StreamCoordinate.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace utils
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
struct Tag
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Parser
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy = CaseSensitiveParserPolicy>
|
||||||
|
class Parser: public Stream, public ParserPolicy
|
||||||
|
{
|
||||||
|
template<class OtherParserPolicy>
|
||||||
|
friend class Parser;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Parser();
|
||||||
|
explicit Parser(std::string streamName, std::istream &istream);
|
||||||
|
|
||||||
|
template<class OtherParser>
|
||||||
|
Parser(OtherParser &&otherParser)
|
||||||
|
{
|
||||||
|
m_stream = std::move(otherParser.m_stream);
|
||||||
|
m_delimiters = std::move(otherParser.m_delimiters);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeComments(const std::string &startSequence, const std::string &endSequence, bool removeEnd);
|
||||||
|
|
||||||
|
char currentCharacter() const;
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
Type parse();
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
bool testAndReturn(const Type &expectedValue);
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
bool testAndSkip(const Type &expectedValue);
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
void expect(const Type &expectedValue);
|
||||||
|
|
||||||
|
std::string parseIdentifier();
|
||||||
|
bool testIdentifierAndReturn(const std::string &identifier);
|
||||||
|
bool testIdentifierAndSkip(const std::string &identifier);
|
||||||
|
|
||||||
|
// TODO: remove
|
||||||
|
bool probeNumber();
|
||||||
|
|
||||||
|
std::string parseLine();
|
||||||
|
|
||||||
|
void skipWhiteSpace();
|
||||||
|
void skipLine();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string parseImpl(Tag<std::string>);
|
||||||
|
char parseImpl(Tag<char>);
|
||||||
|
uint64_t parseImpl(Tag<uint64_t>);
|
||||||
|
int64_t parseImpl(Tag<int64_t>);
|
||||||
|
uint32_t parseImpl(Tag<uint32_t>);
|
||||||
|
int32_t parseImpl(Tag<int32_t>);
|
||||||
|
bool parseImpl(Tag<bool>);
|
||||||
|
|
||||||
|
bool testImpl(const std::string &expectedValue);
|
||||||
|
bool testImpl(char expectedValue);
|
||||||
|
bool testImpl(uint64_t expectedValue);
|
||||||
|
bool testImpl(int64_t expectedValue);
|
||||||
|
bool testImpl(uint32_t expectedValue);
|
||||||
|
bool testImpl(int32_t expectedValue);
|
||||||
|
bool testImpl(bool expectedValue);
|
||||||
|
|
||||||
|
uint64_t parseIntegerBody();
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
Parser<ParserPolicy>::Parser()
|
||||||
|
: Stream()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
Parser<ParserPolicy>::Parser(std::string streamName, std::istream &istream)
|
||||||
|
: Stream(streamName, istream)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
void Parser<ParserPolicy>::skipWhiteSpace()
|
||||||
|
{
|
||||||
|
check();
|
||||||
|
|
||||||
|
while (!atEnd() && ParserPolicy::isWhiteSpaceCharacter(currentCharacter()))
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
void Parser<ParserPolicy>::skipLine()
|
||||||
|
{
|
||||||
|
check();
|
||||||
|
|
||||||
|
while (currentCharacter() != '\n')
|
||||||
|
advance();
|
||||||
|
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
template<typename Type>
|
||||||
|
Type Parser<ParserPolicy>::parse()
|
||||||
|
{
|
||||||
|
return parseImpl(Tag<Type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
template<typename Type>
|
||||||
|
bool Parser<ParserPolicy>::testAndReturn(const Type &expectedValue)
|
||||||
|
{
|
||||||
|
const auto previousPosition = position();
|
||||||
|
|
||||||
|
const auto result = testImpl(expectedValue);
|
||||||
|
|
||||||
|
seek(previousPosition);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
template<typename Type>
|
||||||
|
bool Parser<ParserPolicy>::testAndSkip(const Type &expectedValue)
|
||||||
|
{
|
||||||
|
const auto previousPosition = position();
|
||||||
|
|
||||||
|
const auto result = testImpl(expectedValue);
|
||||||
|
|
||||||
|
if (result == false)
|
||||||
|
seek(previousPosition);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
template<typename Type>
|
||||||
|
void Parser<ParserPolicy>::expect(const Type &expectedValue)
|
||||||
|
{
|
||||||
|
if (testAndSkip(expectedValue))
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::stringstream message;
|
||||||
|
message << "unexpected value, expected “" << expectedValue << "”";
|
||||||
|
|
||||||
|
throw ParserException(coordinate(), message.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
std::string Parser<ParserPolicy>::parseIdentifier()
|
||||||
|
{
|
||||||
|
skipWhiteSpace();
|
||||||
|
|
||||||
|
std::string value;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
const auto character = currentCharacter();
|
||||||
|
|
||||||
|
if (!ParserPolicy::isIdentifierCharacter(character))
|
||||||
|
return value;
|
||||||
|
|
||||||
|
value.push_back(character);
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
bool Parser<ParserPolicy>::testIdentifierAndSkip(const std::string &expectedValue)
|
||||||
|
{
|
||||||
|
return testAndSkip(expectedValue) && !ParserPolicy::isIdentifierCharacter(currentCharacter());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
bool Parser<ParserPolicy>::probeNumber()
|
||||||
|
{
|
||||||
|
const auto previousPosition = position();
|
||||||
|
|
||||||
|
skipWhiteSpace();
|
||||||
|
|
||||||
|
while (!ParserPolicy::isWhiteSpaceCharacter(currentCharacter()))
|
||||||
|
if (!std::isdigit(currentCharacter()))
|
||||||
|
{
|
||||||
|
seek(previousPosition);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
std::string Parser<ParserPolicy>::parseLine()
|
||||||
|
{
|
||||||
|
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<class ParserPolicy>
|
||||||
|
void Parser<ParserPolicy>::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 (atEnd())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_stream.put(' ');
|
||||||
|
position += static_cast<std::streamoff>(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
while (!atEnd())
|
||||||
|
{
|
||||||
|
Position startPosition = m_stream.tellg();
|
||||||
|
|
||||||
|
while (!atEnd())
|
||||||
|
{
|
||||||
|
startPosition = m_stream.tellg();
|
||||||
|
|
||||||
|
if (testAndSkip(startSequence))
|
||||||
|
break;
|
||||||
|
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
Position endPosition = m_stream.tellg();
|
||||||
|
|
||||||
|
while (!atEnd())
|
||||||
|
{
|
||||||
|
endPosition = m_stream.tellg();
|
||||||
|
|
||||||
|
if (testAndSkip(endSequence))
|
||||||
|
break;
|
||||||
|
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (removeEnd)
|
||||||
|
endPosition = m_stream.tellg();
|
||||||
|
|
||||||
|
removeRange(startPosition, endPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_stream.clear();
|
||||||
|
|
||||||
|
m_stream.seekg(inPosition);
|
||||||
|
m_stream.seekp(outPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
char Parser<ParserPolicy>::currentCharacter() const
|
||||||
|
{
|
||||||
|
return ParserPolicy::transformCharacter(Stream::currentCharacter());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
std::string Parser<ParserPolicy>::parseImpl(Tag<std::string>)
|
||||||
|
{
|
||||||
|
skipWhiteSpace();
|
||||||
|
|
||||||
|
const auto startPosition = position();
|
||||||
|
|
||||||
|
while (!ParserPolicy::isWhiteSpaceCharacter(currentCharacter()))
|
||||||
|
advance();
|
||||||
|
|
||||||
|
const auto endPosition = position();
|
||||||
|
const auto length = static_cast<size_t>(endPosition - startPosition);
|
||||||
|
|
||||||
|
std::string value;
|
||||||
|
value.reserve(length);
|
||||||
|
|
||||||
|
seek(startPosition);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
value.push_back(currentCharacter());
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
char Parser<ParserPolicy>::parseImpl(Tag<char>)
|
||||||
|
{
|
||||||
|
const auto value = currentCharacter();
|
||||||
|
|
||||||
|
advance();
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
uint64_t Parser<ParserPolicy>::parseIntegerBody()
|
||||||
|
{
|
||||||
|
check();
|
||||||
|
|
||||||
|
if (!std::isdigit(currentCharacter()))
|
||||||
|
throw ParserException(coordinate(), "could not parse integer value");
|
||||||
|
|
||||||
|
uint64_t value = 0;
|
||||||
|
|
||||||
|
while (!atEnd())
|
||||||
|
{
|
||||||
|
const auto character = currentCharacter();
|
||||||
|
|
||||||
|
if (!std::isdigit(character))
|
||||||
|
break;
|
||||||
|
|
||||||
|
value *= 10;
|
||||||
|
value += character - '0';
|
||||||
|
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
int64_t Parser<ParserPolicy>::parseImpl(Tag<int64_t>)
|
||||||
|
{
|
||||||
|
skipWhiteSpace();
|
||||||
|
|
||||||
|
bool positive = testAndSkip<char>('+') || !testAndSkip<char>('-');
|
||||||
|
|
||||||
|
const auto value = parseIntegerBody();
|
||||||
|
|
||||||
|
return (positive ? value : -value);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
uint64_t Parser<ParserPolicy>::parseImpl(Tag<uint64_t>)
|
||||||
|
{
|
||||||
|
skipWhiteSpace();
|
||||||
|
|
||||||
|
if (currentCharacter() == '-')
|
||||||
|
throw ParserException(coordinate(), "expected unsigned integer, got signed one");
|
||||||
|
|
||||||
|
return parseIntegerBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
int32_t Parser<ParserPolicy>::parseImpl(Tag<int32_t>)
|
||||||
|
{
|
||||||
|
return static_cast<int32_t>(parseImpl(Tag<int64_t>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
uint32_t Parser<ParserPolicy>::parseImpl(Tag<uint32_t>)
|
||||||
|
{
|
||||||
|
return static_cast<uint32_t>(parseImpl(Tag<uint64_t>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
bool Parser<ParserPolicy>::parseImpl(Tag<bool>)
|
||||||
|
{
|
||||||
|
skipWhiteSpace();
|
||||||
|
|
||||||
|
if (testAndSkip<char>('0'))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (testAndSkip<char>('1'))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
throw ParserException(coordinate(), "could not parse Boolean value");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
bool Parser<ParserPolicy>::testImpl(const std::string &expectedValue)
|
||||||
|
{
|
||||||
|
if (!ParserPolicy::isWhiteSpaceCharacter(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;
|
||||||
|
});
|
||||||
|
|
||||||
|
return (match == expectedValue.cend());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
bool Parser<ParserPolicy>::testImpl(char expectedValue)
|
||||||
|
{
|
||||||
|
const auto result = (currentCharacter() == expectedValue);
|
||||||
|
|
||||||
|
advance();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
bool Parser<ParserPolicy>::testImpl(int64_t expectedValue)
|
||||||
|
{
|
||||||
|
const auto value = parseImpl(Tag<int64_t>());
|
||||||
|
|
||||||
|
return (value == expectedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
bool Parser<ParserPolicy>::testImpl(uint64_t expectedValue)
|
||||||
|
{
|
||||||
|
const auto value = parseImpl(Tag<uint64_t>());
|
||||||
|
|
||||||
|
return (value == expectedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
bool Parser<ParserPolicy>::testImpl(int32_t expectedValue)
|
||||||
|
{
|
||||||
|
return testImpl(static_cast<int64_t>(expectedValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
bool Parser<ParserPolicy>::testImpl(uint32_t expectedValue)
|
||||||
|
{
|
||||||
|
return testImpl(static_cast<uint64_t>(expectedValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class ParserPolicy>
|
||||||
|
bool Parser<ParserPolicy>::testImpl(bool expectedValue)
|
||||||
|
{
|
||||||
|
const auto value = parseImpl(Tag<bool>());
|
||||||
|
|
||||||
|
return (value == expectedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@@ -4,6 +4,8 @@
|
|||||||
#include <exception>
|
#include <exception>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <plasp/utils/StreamCoordinate.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 StreamCoordinate &coordinate)
|
||||||
|
: ParserException(coordinate, "unspecified parser error")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit ParserException(const char *message)
|
explicit ParserException(const StreamCoordinate &coordinate, const char *message)
|
||||||
: m_message(message)
|
: ParserException(coordinate, static_cast<std::string>(message))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit ParserException(const std::string &message)
|
explicit ParserException(const StreamCoordinate &coordinate, const std::string &message)
|
||||||
: m_message(message)
|
: m_coordinate{coordinate},
|
||||||
|
m_message{message},
|
||||||
|
m_plainMessage{m_coordinate.sectionName + ":" + std::to_string(m_coordinate.row)
|
||||||
|
+ ":" + std::to_string(m_coordinate.column) + " " + m_message}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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 StreamCoordinate &coordinate() const
|
||||||
|
{
|
||||||
|
return m_coordinate;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string &message() const
|
||||||
|
{
|
||||||
|
return m_message;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
StreamCoordinate m_coordinate;
|
||||||
std::string m_message;
|
std::string m_message;
|
||||||
|
std::string m_plainMessage;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
62
include/plasp/utils/ParserPolicy.h
Normal file
62
include/plasp/utils/ParserPolicy.h
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#ifndef __PLASP__UTILS__PARSER_POLICY_H
|
||||||
|
#define __PLASP__UTILS__PARSER_POLICY_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace utils
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// ParserPolicy
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class CaseSensitiveParserPolicy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr char transformCharacter(char c) noexcept
|
||||||
|
{
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isWhiteSpaceCharacter(char c)
|
||||||
|
{
|
||||||
|
return std::iswspace(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isIdentifierCharacter(char c)
|
||||||
|
{
|
||||||
|
return std::isgraph(c);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class CaseInsensitiveParserPolicy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static char transformCharacter(char c) noexcept
|
||||||
|
{
|
||||||
|
return std::tolower(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isWhiteSpaceCharacter(char c)
|
||||||
|
{
|
||||||
|
return std::iswspace(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isIdentifierCharacter(char c)
|
||||||
|
{
|
||||||
|
return std::isgraph(c);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
84
include/plasp/utils/Stream.h
Normal file
84
include/plasp/utils/Stream.h
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
#ifndef __PLASP__UTILS__STREAM_H
|
||||||
|
#define __PLASP__UTILS__STREAM_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <iterator>
|
||||||
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
#include <plasp/utils/ParserException.h>
|
||||||
|
#include <plasp/utils/StreamCoordinate.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace utils
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Stream
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Stream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using Position = std::stringstream::pos_type;
|
||||||
|
|
||||||
|
struct Delimiter
|
||||||
|
{
|
||||||
|
Position position;
|
||||||
|
std::string sectionName;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Stream();
|
||||||
|
explicit Stream(std::string streamName, std::istream &istream);
|
||||||
|
|
||||||
|
Stream(const Stream &other) = delete;
|
||||||
|
Stream &operator=(const Stream &other) = delete;
|
||||||
|
|
||||||
|
Stream(Stream &&other)
|
||||||
|
: m_stream{std::move(other.m_stream)},
|
||||||
|
m_delimiters{std::move(other.m_delimiters)}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream &operator=(Stream &&other)
|
||||||
|
{
|
||||||
|
m_stream = std::move(other.m_stream);
|
||||||
|
m_delimiters = std::move(other.m_delimiters);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~Stream() = default;
|
||||||
|
|
||||||
|
void read(std::string streamName, std::istream &istream);
|
||||||
|
void read(const boost::filesystem::path &path);
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
void seek(Position position);
|
||||||
|
Position position() const;
|
||||||
|
StreamCoordinate coordinate() const;
|
||||||
|
|
||||||
|
char currentCharacter() const;
|
||||||
|
void advance();
|
||||||
|
bool atEnd() const;
|
||||||
|
|
||||||
|
void check() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
mutable std::stringstream m_stream;
|
||||||
|
|
||||||
|
std::vector<Delimiter> m_delimiters;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
29
include/plasp/utils/StreamCoordinate.h
Normal file
29
include/plasp/utils/StreamCoordinate.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef __PLASP__UTILS__STREAM_COORDINATE_H
|
||||||
|
#define __PLASP__UTILS__STREAM_COORDINATE_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace utils
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// StreamCoordinate
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct StreamCoordinate
|
||||||
|
{
|
||||||
|
std::string sectionName;
|
||||||
|
size_t row;
|
||||||
|
size_t column;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@@ -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/expressions/Type.h>
|
||||||
|
#include <plasp/utils/IO.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Action
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Action::parseDeclaration(Context &context, Domain &domain)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
auto action = std::make_unique<Action>(Action());
|
||||||
|
|
||||||
|
action->m_name = parser.parseIdentifier();
|
||||||
|
|
||||||
|
parser.expect<std::string>(":parameters");
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
|
||||||
|
ExpressionContext expressionContext(domain, action->m_parameters);
|
||||||
|
|
||||||
|
// Read parameters
|
||||||
|
expressions::Variable::parseTypedDeclarations(context, expressionContext);
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
|
||||||
|
// Parse preconditions and effects
|
||||||
|
while (!parser.testAndReturn(')'))
|
||||||
|
{
|
||||||
|
parser.expect<std::string>(":");
|
||||||
|
|
||||||
|
if (parser.testIdentifierAndSkip("precondition"))
|
||||||
|
action->m_precondition = parsePreconditionExpression(context, expressionContext);
|
||||||
|
else if (parser.testIdentifierAndSkip("effect"))
|
||||||
|
action->m_effect = parseEffectExpression(context, expressionContext);
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
208
src/plasp/pddl/Description.cpp
Normal file
208
src/plasp/pddl/Description.cpp
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
#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.read("std::cin", istream);
|
||||||
|
description.parse();
|
||||||
|
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Description Description::fromFile(const std::string &path)
|
||||||
|
{
|
||||||
|
Description description;
|
||||||
|
|
||||||
|
description.m_context.parser.read(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.read(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.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.atEnd())
|
||||||
|
{
|
||||||
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>("define");
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
|
||||||
|
if (parser.testAndSkip<std::string>("domain"))
|
||||||
|
{
|
||||||
|
if (m_domainPosition != -1)
|
||||||
|
throw utils::ParserException(parser.coordinate(), "PDDL description may not contain two domains");
|
||||||
|
|
||||||
|
m_domainPosition = position;
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
m_domain->findSections();
|
||||||
|
}
|
||||||
|
else if (m_context.parser.testAndSkip<std::string>("problem"))
|
||||||
|
{
|
||||||
|
if (m_problemPosition != -1)
|
||||||
|
throw utils::ParserException(parser.coordinate(), "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.coordinate(), "unknown PDDL section “" + sectionIdentifier + "”");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_context.parser.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Description::checkConsistency()
|
||||||
|
{
|
||||||
|
m_domain->checkConsistency();
|
||||||
|
m_problem->checkConsistency();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
418
src/plasp/pddl/Domain.cpp
Normal file
418
src/plasp/pddl/Domain.cpp
Normal file
@@ -0,0 +1,418 @@
|
|||||||
|
#include <plasp/pddl/Domain.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <plasp/pddl/ConsistencyException.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();
|
||||||
|
|
||||||
|
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.coordinate(), "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.testIdentifierAndSkip("requirements"))
|
||||||
|
setSectionPosition("requirements", m_requirementsPosition, position, true);
|
||||||
|
else if (parser.testIdentifierAndSkip("types"))
|
||||||
|
setSectionPosition("types", m_typesPosition, position, true);
|
||||||
|
else if (parser.testIdentifierAndSkip("constants"))
|
||||||
|
setSectionPosition("constants", m_constantsPosition, position, true);
|
||||||
|
else if (parser.testIdentifierAndSkip("predicates"))
|
||||||
|
setSectionPosition("predicates", m_predicatesPosition, position, true);
|
||||||
|
else if (parser.testIdentifierAndSkip("action"))
|
||||||
|
{
|
||||||
|
m_actionPositions.emplace_back(-1);
|
||||||
|
setSectionPosition("action", m_actionPositions.back(), position);
|
||||||
|
}
|
||||||
|
else if (parser.testIdentifierAndSkip("functions")
|
||||||
|
|| parser.testIdentifierAndSkip("constraints")
|
||||||
|
|| parser.testIdentifierAndSkip("durative-action")
|
||||||
|
|| parser.testIdentifierAndSkip("derived"))
|
||||||
|
{
|
||||||
|
parser.seek(sectionIdentifierPosition);
|
||||||
|
|
||||||
|
const auto sectionIdentifier = parser.parseIdentifier();
|
||||||
|
|
||||||
|
m_context.logger.logWarning(parser.coordinate(), "section type “" + sectionIdentifier + "” currently unsupported");
|
||||||
|
|
||||||
|
parser.seek(sectionIdentifierPosition);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto sectionIdentifier = parser.parseIdentifier();
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
throw utils::ParserException(parser.coordinate(), "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.coordinate(), "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
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
254
src/plasp/pddl/Expression.cpp
Normal file
254
src/plasp/pddl/Expression.cpp
Normal file
@@ -0,0 +1,254 @@
|
|||||||
|
#include <plasp/pddl/Expression.h>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/Domain.h>
|
||||||
|
#include <plasp/pddl/ExpressionContext.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.testIdentifierAndSkip("forall")
|
||||||
|
|| parser.testIdentifierAndSkip("preference"))
|
||||||
|
{
|
||||||
|
// TODO: refactor
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier();
|
||||||
|
|
||||||
|
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.testIdentifierAndSkip("exists")
|
||||||
|
|| parser.testIdentifierAndSkip("forall")
|
||||||
|
|| parser.testIdentifierAndSkip("-")
|
||||||
|
|| parser.testIdentifierAndSkip("=")
|
||||||
|
|| parser.testIdentifierAndSkip("*")
|
||||||
|
|| parser.testIdentifierAndSkip("+")
|
||||||
|
|| parser.testIdentifierAndSkip("-")
|
||||||
|
|| parser.testIdentifierAndSkip("/")
|
||||||
|
|| parser.testIdentifierAndSkip(">")
|
||||||
|
|| parser.testIdentifierAndSkip("<")
|
||||||
|
|| parser.testIdentifierAndSkip("=")
|
||||||
|
|| parser.testIdentifierAndSkip(">=")
|
||||||
|
|| parser.testIdentifierAndSkip("<="))
|
||||||
|
{
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier();
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
return expressions::Unsupported::parse(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier();
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
throw utils::ParserException(parser.coordinate(), "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.testIdentifierAndSkip("forall")
|
||||||
|
|| parser.testIdentifierAndSkip("when"))
|
||||||
|
{
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier();
|
||||||
|
|
||||||
|
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.testIdentifierAndSkip("=")
|
||||||
|
|| parser.testIdentifierAndSkip("assign")
|
||||||
|
|| parser.testIdentifierAndSkip("scale-up")
|
||||||
|
|| parser.testIdentifierAndSkip("scale-down")
|
||||||
|
|| parser.testIdentifierAndSkip("increase")
|
||||||
|
|| parser.testIdentifierAndSkip("decrease"))
|
||||||
|
{
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier();
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
return expressions::Unsupported::parse(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier();
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
throw utils::ParserException(parser.coordinate(), "expression type “" + expressionIdentifier + "” unknown or not allowed in this context");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ExpressionPointer parsePredicate(Context &context, ExpressionContext &expressionContext)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
ExpressionPointer expression;
|
||||||
|
|
||||||
|
if ((expression = expressions::Predicate::parse(context, expressionContext)))
|
||||||
|
return expression;
|
||||||
|
|
||||||
|
throw utils::ParserException(parser.coordinate(), "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.testAndSkip<std::string>("("))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const auto expressionIdentifierPosition = parser.position();
|
||||||
|
|
||||||
|
if (parser.testIdentifierAndSkip("="))
|
||||||
|
{
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier();
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
89
src/plasp/pddl/InitialState.cpp
Normal file
89
src/plasp/pddl/InitialState.cpp
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
#include <plasp/pddl/InitialState.h>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/ExpressionContext.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.testIdentifierAndSkip("="))
|
||||||
|
{
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier();
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
return expressions::Unsupported::parse(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier();
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
throw utils::ParserException(parser.coordinate(), "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;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
398
src/plasp/pddl/Problem.cpp
Normal file
398
src/plasp/pddl/Problem.cpp
Normal file
@@ -0,0 +1,398 @@
|
|||||||
|
#include <plasp/pddl/Problem.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Domain.h>
|
||||||
|
#include <plasp/pddl/ExpressionContext.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();
|
||||||
|
|
||||||
|
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.coordinate(), "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.testIdentifierAndSkip("domain"))
|
||||||
|
setSectionPosition("domain", m_domainPosition, position, true);
|
||||||
|
else if (parser.testIdentifierAndSkip("requirements"))
|
||||||
|
setSectionPosition("requirements", m_requirementsPosition, position, true);
|
||||||
|
else if (parser.testIdentifierAndSkip("objects"))
|
||||||
|
setSectionPosition("objects", m_objectsPosition, position, true);
|
||||||
|
else if (parser.testIdentifierAndSkip("init"))
|
||||||
|
setSectionPosition("init", m_initialStatePosition, position, true);
|
||||||
|
else if (parser.testIdentifierAndSkip("goal"))
|
||||||
|
setSectionPosition("goal", m_goalPosition, position, true);
|
||||||
|
else if (parser.testIdentifierAndSkip("constraints")
|
||||||
|
|| parser.testIdentifierAndSkip("metric")
|
||||||
|
|| parser.testIdentifierAndSkip("length"))
|
||||||
|
{
|
||||||
|
parser.seek(sectionIdentifierPosition);
|
||||||
|
|
||||||
|
const auto sectionIdentifier = parser.parseIdentifier();
|
||||||
|
|
||||||
|
m_context.logger.logWarning(parser.coordinate(), "section type “" + sectionIdentifier + "” currently unsupported");
|
||||||
|
|
||||||
|
parser.seek(sectionIdentifierPosition);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto sectionIdentifier = parser.parseIdentifier();
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
throw utils::ParserException(parser.coordinate(), "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();
|
||||||
|
|
||||||
|
if (m_domain.name() != domainName)
|
||||||
|
throw utils::ParserException(parser.coordinate(), "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()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
135
src/plasp/pddl/Requirement.cpp
Normal file
135
src/plasp/pddl/Requirement.cpp
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
#include <plasp/pddl/Requirement.h>
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
#include <boost/assign.hpp>
|
||||||
|
#include <boost/bimap.hpp>
|
||||||
|
|
||||||
|
#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)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
const auto requirementName = parser.parseIdentifier();
|
||||||
|
|
||||||
|
const auto match = requirementTypesToPDDL.right.find(requirementName);
|
||||||
|
|
||||||
|
if (match == requirementTypesToPDDL.right.end())
|
||||||
|
throw utils::ParserException(parser.coordinate(), "unknown PDDL requirement “" + requirementName + "”");
|
||||||
|
|
||||||
|
const auto requirementType = match->second;
|
||||||
|
|
||||||
|
if (requirementType == Requirement::Type::GoalUtilities)
|
||||||
|
context.logger.logWarning(parser.coordinate(), "requirement “goal-utilities” is not part of the PDDL 3.1 specification");
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
568
src/plasp/pddl/TranslatorASP.cpp
Normal file
568
src/plasp/pddl/TranslatorASP.cpp
Normal file
@@ -0,0 +1,568 @@
|
|||||||
|
#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") << "("
|
||||||
|
<< 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") << "("
|
||||||
|
<< 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("has") << "(" << utils::Variable("X") << ", "
|
||||||
|
<< utils::Keyword("type") << "(" << parentTypeName << ")) :- "
|
||||||
|
<< utils::Keyword("has") << "(" << utils::Variable("X") << ", "
|
||||||
|
<< utils::Keyword("type") << "(" << typeName << "))." << std::endl;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TranslatorASP::translatePredicates() const
|
||||||
|
{
|
||||||
|
m_outputStream << utils::Heading2("variables");
|
||||||
|
|
||||||
|
const auto &predicates = m_description.domain().predicates();
|
||||||
|
|
||||||
|
const auto printPredicateName =
|
||||||
|
[&](const auto &predicate)
|
||||||
|
{
|
||||||
|
m_outputStream
|
||||||
|
<< utils::escapeASP(predicate->name());
|
||||||
|
|
||||||
|
this->translateVariablesHead(predicate->arguments());
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto printValueRule =
|
||||||
|
[&](const auto &predicate, const auto &value)
|
||||||
|
{
|
||||||
|
m_outputStream
|
||||||
|
<< utils::Keyword("contains") << "("
|
||||||
|
<< utils::Keyword("variable") << "(";
|
||||||
|
|
||||||
|
printPredicateName(predicate);
|
||||||
|
|
||||||
|
m_outputStream
|
||||||
|
<< "), " << utils::Keyword("value") << "(";
|
||||||
|
|
||||||
|
printPredicateName(predicate);
|
||||||
|
|
||||||
|
m_outputStream << ", " << utils::Keyword(value) << "))";
|
||||||
|
|
||||||
|
this->translateVariablesBody(predicate->arguments());
|
||||||
|
|
||||||
|
m_outputStream << "." << std::endl;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::for_each(predicates.cbegin(), predicates.cend(),
|
||||||
|
[&](const auto &predicate)
|
||||||
|
{
|
||||||
|
m_outputStream
|
||||||
|
<< std::endl
|
||||||
|
<< utils::Keyword("variable") << "("
|
||||||
|
<< utils::Keyword("variable") << "(";
|
||||||
|
|
||||||
|
printPredicateName(predicate);
|
||||||
|
|
||||||
|
m_outputStream << "))";
|
||||||
|
|
||||||
|
this->translateVariablesBody(predicate->arguments());
|
||||||
|
|
||||||
|
m_outputStream << "." << std::endl;
|
||||||
|
|
||||||
|
printValueRule(predicate, "true");
|
||||||
|
printValueRule(predicate, "false");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
// TODO: rename
|
||||||
|
const auto translateLiteral =
|
||||||
|
[&](const auto &ruleHead, const auto &literal, bool enumerateEffects = false)
|
||||||
|
{
|
||||||
|
m_outputStream << std::endl << utils::Keyword(ruleHead) << "(";
|
||||||
|
|
||||||
|
printActionName(*action);
|
||||||
|
|
||||||
|
// TODO: implement conditional effects
|
||||||
|
if (enumerateEffects)
|
||||||
|
m_outputStream << ", " << utils::Keyword("effect") << "(unconditional)";
|
||||||
|
|
||||||
|
m_outputStream << ", ";
|
||||||
|
|
||||||
|
this->translateLiteral(literal);
|
||||||
|
|
||||||
|
m_outputStream << ") :- " << utils::Keyword("action") << "(";
|
||||||
|
|
||||||
|
printActionName(*action);
|
||||||
|
|
||||||
|
m_outputStream << ").";
|
||||||
|
};
|
||||||
|
|
||||||
|
m_outputStream << std::endl;
|
||||||
|
|
||||||
|
// Name
|
||||||
|
m_outputStream << utils::Keyword("action") << "(";
|
||||||
|
printActionName(*action);
|
||||||
|
m_outputStream << ")";
|
||||||
|
|
||||||
|
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, true);
|
||||||
|
}
|
||||||
|
// 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, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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") << "("
|
||||||
|
<< utils::Keyword("constant") << "("
|
||||||
|
<< constantName
|
||||||
|
<< "))." << std::endl;
|
||||||
|
|
||||||
|
const auto *type = constant->type();
|
||||||
|
|
||||||
|
if (type != nullptr)
|
||||||
|
{
|
||||||
|
m_outputStream << utils::Keyword("has") << "("
|
||||||
|
<< utils::Keyword("constant") << "(" << constantName << "), "
|
||||||
|
<< utils::Keyword("type") << "(" << utils::escapeASP(type->name()) << "))." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_outputStream << utils::Keyword("has") << "("
|
||||||
|
<< 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("has") << "("
|
||||||
|
<< utils::Variable(utils::escapeASPVariable(variable.name())) << ", "
|
||||||
|
<< utils::Keyword("type") << "(" << utils::escapeASP(type.name()) << "))";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_outputStream << utils::Keyword("has") << "("
|
||||||
|
<< 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)
|
||||||
|
{
|
||||||
|
const auto &predicate = dynamic_cast<const expressions::Predicate &>(literal);
|
||||||
|
|
||||||
|
m_outputStream << utils::Keyword("variable") << "(";
|
||||||
|
this->translatePredicate(predicate);
|
||||||
|
m_outputStream << "), " << utils::Keyword("value") << "(";
|
||||||
|
this->translatePredicate(predicate);
|
||||||
|
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());
|
||||||
|
|
||||||
|
m_outputStream << utils::Keyword("variable") << "(";
|
||||||
|
this->translatePredicate(predicate);
|
||||||
|
m_outputStream << "), " << utils::Keyword("value") << "(";
|
||||||
|
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::escapeASP(predicate.name());
|
||||||
|
|
||||||
|
const auto &arguments = predicate.arguments();
|
||||||
|
|
||||||
|
if (arguments.empty())
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
const auto &predicate = dynamic_cast<const expressions::Predicate &>(*fact);
|
||||||
|
|
||||||
|
m_outputStream << utils::Keyword("variable") << "(";
|
||||||
|
this->translatePredicate(predicate);
|
||||||
|
m_outputStream << "), " << utils::Keyword("value") << "(";
|
||||||
|
this->translatePredicate(predicate);
|
||||||
|
m_outputStream << ", " << utils::Keyword("true") << ")";
|
||||||
|
}
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
244
src/plasp/pddl/expressions/Constant.cpp
Normal file
244
src/plasp/pddl/expressions/Constant.cpp
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
#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();
|
||||||
|
|
||||||
|
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.testAndSkip<char>('-'))
|
||||||
|
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.coordinate(), "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(parser.coordinate(), "constant has undeclared type");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Constant *Constant::parseAndFind(Context &context, const Domain &domain)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
const auto constantName = parser.parseIdentifier();
|
||||||
|
|
||||||
|
auto *constant = parseAndFind(constantName, domain.constants());
|
||||||
|
|
||||||
|
if (constant != nullptr)
|
||||||
|
return constant;
|
||||||
|
|
||||||
|
throw utils::ParserException(parser.coordinate(), "constant “" + constantName + "” used but never declared");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Constant *Constant::parseAndFind(Context &context, const Problem &problem)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
const auto constantName = parser.parseIdentifier();
|
||||||
|
|
||||||
|
auto *constant = parseAndFind(constantName, problem.domain().constants());
|
||||||
|
|
||||||
|
if (constant)
|
||||||
|
return constant;
|
||||||
|
|
||||||
|
constant = parseAndFind(constantName, problem.objects());
|
||||||
|
|
||||||
|
if (constant)
|
||||||
|
return constant;
|
||||||
|
|
||||||
|
throw utils::ParserException(parser.coordinate(), "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";
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
src/plasp/pddl/expressions/Imply.cpp
Normal file
23
src/plasp/pddl/expressions/Imply.cpp
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#include <plasp/pddl/expressions/Imply.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace expressions
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Imply
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// TODO: make static character string literal
|
||||||
|
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";
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
175
src/plasp/pddl/expressions/Predicate.cpp
Normal file
175
src/plasp/pddl/expressions/Predicate.cpp
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
#include <plasp/pddl/expressions/Predicate.h>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/Domain.h>
|
||||||
|
#include <plasp/pddl/ExpressionContext.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.testAndSkip<std::string>("("))
|
||||||
|
{
|
||||||
|
parser.seek(position);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto predicateName = parser.parseIdentifier();
|
||||||
|
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.testAndSkip<std::string>("("))
|
||||||
|
{
|
||||||
|
parser.seek(position);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto predicateName = parser.parseIdentifier();
|
||||||
|
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;
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
while (parser.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
if (parser.currentCharacter() == '?')
|
||||||
|
throw utils::ParserException(parser.coordinate(), "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;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
84
src/plasp/pddl/expressions/PredicateDeclaration.cpp
Normal file
84
src/plasp/pddl/expressions/PredicateDeclaration.cpp
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
#include <plasp/pddl/expressions/PredicateDeclaration.h>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/Domain.h>
|
||||||
|
#include <plasp/pddl/ExpressionContext.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();
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
174
src/plasp/pddl/expressions/PrimitiveType.cpp
Normal file
174
src/plasp/pddl/expressions/PrimitiveType.cpp
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
#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();
|
||||||
|
|
||||||
|
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.testAndSkip<char>('-'))
|
||||||
|
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 &parser = context.parser;
|
||||||
|
|
||||||
|
auto &types = domain.types();
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
const auto typeName = parser.parseIdentifier();
|
||||||
|
|
||||||
|
if (typeName.empty())
|
||||||
|
throw utils::ParserException(parser.coordinate(), "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(parser.coordinate(), "primitive type “" + typeName + "” should be declared");
|
||||||
|
types.emplace_back(std::make_unique<expressions::PrimitiveType>(typeName));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw utils::ParserException(parser.coordinate(), "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);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
46
src/plasp/pddl/expressions/Unsupported.cpp
Normal file
46
src/plasp/pddl/expressions/Unsupported.cpp
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#include <plasp/pddl/expressions/Unsupported.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();
|
||||||
|
|
||||||
|
context.logger.logWarning(parser.coordinate(), "expression type “" + expression->m_type + "” currently unsupported in this context");
|
||||||
|
|
||||||
|
skipSection(parser);
|
||||||
|
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::string &Unsupported::type() const
|
||||||
|
{
|
||||||
|
return m_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
204
src/plasp/pddl/expressions/Variable.cpp
Normal file
204
src/plasp/pddl/expressions/Variable.cpp
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
#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/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)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
parser.expect<std::string>("?");
|
||||||
|
|
||||||
|
auto variable = std::make_unique<Variable>(Variable());
|
||||||
|
|
||||||
|
variable->m_name = parser.parseIdentifier();
|
||||||
|
|
||||||
|
// 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(parser.coordinate(), "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.testAndSkip<char>('-'))
|
||||||
|
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.coordinate(), "variable has undeclared type");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const Variable *Variable::parseAndFind(Context &context, const ExpressionContext &expressionContext)
|
||||||
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
parser.expect<std::string>("?");
|
||||||
|
|
||||||
|
const auto variableName = parser.parseIdentifier();
|
||||||
|
|
||||||
|
const auto &variables = expressionContext.parameters;
|
||||||
|
|
||||||
|
const auto match = std::find_if(variables.cbegin(), variables.cend(),
|
||||||
|
[&](const auto &variable)
|
||||||
|
{
|
||||||
|
return variable->name() == variableName;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (match == variables.cend())
|
||||||
|
throw utils::ParserException(parser.coordinate(), "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,23 @@ Description::Description()
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Description Description::fromStream(std::istream &istream)
|
Description Description::fromParser(utils::Parser<> &&parser)
|
||||||
{
|
{
|
||||||
Description description;
|
Description description;
|
||||||
|
description.parseContent(parser);
|
||||||
|
|
||||||
std::setlocale(LC_NUMERIC, "C");
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
istream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
description.parseVersionSection(istream);
|
Description Description::fromStream(std::istream &istream)
|
||||||
description.parseMetricSection(istream);
|
{
|
||||||
description.parseVariablesSection(istream);
|
utils::Parser<> parser;
|
||||||
description.parseMutexSection(istream);
|
parser.read("std::cin", istream);
|
||||||
description.parseInitialStateSection(istream);
|
|
||||||
description.parseGoalSection(istream);
|
Description description;
|
||||||
description.parseOperatorSection(istream);
|
description.parseContent(parser);
|
||||||
description.parseAxiomSection(istream);
|
|
||||||
|
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
@@ -54,11 +54,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.read(path);
|
||||||
|
|
||||||
return Description::fromStream(fileStream);
|
Description description;
|
||||||
|
description.parseContent(parser);
|
||||||
|
|
||||||
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -149,85 +153,111 @@ bool Description::usesConditionalEffects() const
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Description::parseVersionSection(std::istream &istream) const
|
bool Description::hasRequirements() const
|
||||||
{
|
{
|
||||||
utils::parseExpected<std::string>(istream, "begin_version");
|
return usesActionCosts() || usesAxiomRules() || usesConditionalEffects();
|
||||||
|
}
|
||||||
|
|
||||||
const auto formatVersion = utils::parse<size_t>(istream);
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Description::parseContent(utils::Parser<> &parser)
|
||||||
|
{
|
||||||
|
parseVersionSection(parser);
|
||||||
|
parseMetricSection(parser);
|
||||||
|
parseVariablesSection(parser);
|
||||||
|
parseMutexSection(parser);
|
||||||
|
parseInitialStateSection(parser);
|
||||||
|
parseGoalSection(parser);
|
||||||
|
parseOperatorSection(parser);
|
||||||
|
parseAxiomSection(parser);
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
if (!parser.atEnd())
|
||||||
|
throw utils::ParserException(parser.coordinate(), "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.coordinate(), "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.coordinate(), "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 << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user