105 Commits

Author SHA1 Message Date
b44c04d3c0 Version bump for release 3.0.2. 2016-08-18 15:55:51 +02:00
220b9959a3 Added IPC 2004 Satellite example instances. 2016-08-18 15:51:58 +02:00
f8ec341015 Added IPC 2006 TPP example instances. 2016-08-18 15:43:14 +02:00
3ceeb3ae40 Added IPC 2002 Driver Log example instances. 2016-08-18 15:29:27 +02:00
56f0091f1e Added IPC 2002 Depots example instances. 2016-08-18 15:25:10 +02:00
ec886e345b Added IPC 2000 Elevator example instances. 2016-08-18 15:06:53 +02:00
786eabb748 Added IPC 2000 Blocks World example instances. 2016-08-18 15:00:31 +02:00
fa18dc7979 Restructured example instances for consistency. 2016-08-18 14:53:26 +02:00
136f9ed00a Added IPC 1998 Gripper example instances. 2016-08-18 14:40:06 +02:00
e312740629 Fixed syntax error in output. 2016-08-18 14:39:40 +02:00
31d0a1fb38 Turned exception about unspecified requirements into a warning, now also for problems. 2016-08-18 14:30:47 +02:00
ca30f8a815 Turned exception about unspecified requirements into a warning. 2016-08-18 14:29:17 +02:00
21c337e0fa Removed now obsolete ASP variable handling for PDDL. 2016-08-18 00:25:47 +02:00
8251652445 Implemented parameter name normalization for PDDL to avoid escaping the names. 2016-08-18 00:24:10 +02:00
5e28dd046b Further simplified the output of the PDDL variable value facts. 2016-08-18 00:00:50 +02:00
363070b579 Replaced the two rules for the values of a PDDL variable with a single one. 2016-08-17 23:31:31 +02:00
63ed1299ec Updated documentation to recent change of PDDL translator output. 2016-08-17 19:05:01 +02:00
7bd483cd7e Added rule to PDDL translator output to make all unspecified initial state variables false by default. 2016-08-17 19:02:51 +02:00
91019f52aa Fixed issue with unsupported expression negations. 2016-08-16 18:58:30 +02:00
69a26cb22f Fixed undetected issue with unsupported negations. 2016-08-16 18:43:37 +02:00
cdb06fa5bf Improved output format and highlighting. 2016-08-16 18:35:55 +02:00
9c76ce7174 Documented type inheritance. 2016-08-16 18:07:18 +02:00
676dc44619 Updated meta encoding to new feature requirement format. 2016-08-15 18:24:51 +02:00
b8a3019e5b Made unconditional effects a keyword. 2016-08-15 16:59:28 +02:00
e0a15849df Updated documentation to changes of axiom rule output format. 2016-08-15 16:48:17 +02:00
ef57f27c6a Changed output format of axiom rules for consistency. 2016-08-15 16:33:33 +02:00
169c5ae8e9 Fixed typo. 2016-08-15 15:26:34 +02:00
760143a4a2 Documented CMake option for building tests. 2016-08-15 02:23:05 +02:00
b100bcd446 Disabled tests by default. 2016-08-15 02:23:05 +02:00
04ddbaabae Version bump after release 3.0.2 RC 1. 2016-08-14 17:40:51 +02:00
4a2882711d Version bump for release 3.0.2 RC 1. 2016-08-14 17:36:59 +02:00
08113c961a Continuously incrementing effect IDs, with a special identifier for unconditional effects. 2016-08-14 17:21:41 +02:00
e2da46e20a Updated change log with documentation of output format. 2016-08-14 16:37:31 +02:00
0cf44da917 Minor formatting. 2016-08-14 16:35:38 +02:00
d03638919a Added more detail to the command-line interface documentation. 2016-08-14 16:34:39 +02:00
f5d342a442 Minor formatting. 2016-08-14 16:33:11 +02:00
06cab2f098 Put command-line interface documentation in a separate documentation file. 2016-08-14 16:31:23 +02:00
9d67ae800d Put building instructions in a separate documentation file. 2016-08-14 16:27:43 +02:00
d2a1030320 Added link to output format to the readme file. 2016-08-14 16:23:28 +02:00
5c17d23606 Added list of supported feature requirements. 2016-08-14 16:15:43 +02:00
bc1759aedf Minor formatting. 2016-08-14 16:09:36 +02:00
b9aef10db3 Documented axiom rules. 2016-08-14 16:07:45 +02:00
bdb6ac9fba Changed output format of axiom rules. 2016-08-14 16:02:28 +02:00
4d5f935e82 Minor formatting. 2016-08-14 16:01:39 +02:00
d604e44dff Documented mutex groups. 2016-08-14 16:00:31 +02:00
2c37da4cb4 Clarification about variables’ value uniqueness. 2016-08-14 16:00:09 +02:00
741078c4fd Minor formatting. 2016-08-14 15:50:49 +02:00
e101cf2aab Documented action costs. 2016-08-14 15:49:34 +02:00
3dfae74468 Documented goal. 2016-08-14 15:47:49 +02:00
2363f42bc9 Minor clarification in the documentation concerning action sequences. 2016-08-14 15:46:12 +02:00
491454ca3c Extended introduction to the documentation. 2016-08-14 15:44:14 +02:00
562b2296e5 Documented initial state. 2016-08-14 15:39:25 +02:00
3535afb1e1 Minor clarification concerning constants and objects. 2016-08-14 15:31:23 +02:00
7a63e4abb9 Documented constants and objects. 2016-08-14 15:29:27 +02:00
2281cd1cd4 Documented actions. 2016-08-14 15:14:27 +02:00
4037b339e4 Changed keyword for conditions of conditional effects. 2016-08-14 15:14:13 +02:00
00c3140f3b Restructured output format documentation once more and documented variables. 2016-08-14 14:58:04 +02:00
0fb282d153 Changed output format of feature requirements. 2016-08-14 14:55:46 +02:00
7a73f99581 Updated change log with recent fixes in SAS output formatting. 2016-08-13 19:14:04 +02:00
bdd68f04e1 Minor cleanup in documentation. 2016-08-13 19:02:05 +02:00
a5a300b150 Documented constants and objects. 2016-08-13 18:59:11 +02:00
197cec923e Added introductory example to output format documentation. 2016-08-13 18:47:01 +02:00
c391a1f566 Removed unwanted newline in SAS output. 2016-08-13 18:44:18 +02:00
1727113a8b Documented types. 2016-08-13 18:07:17 +02:00
18ac959970 Restructured documentation of feature requirements and added an example. 2016-08-13 17:52:27 +02:00
d00c5bb753 Minor rephrasing in documentation. 2016-08-13 17:42:02 +02:00
ffcf07b935 Documented feature requirements. 2016-08-13 17:39:39 +02:00
042531abc3 Started documenting the unified output format. 2016-08-13 13:35:30 +02:00
4fc7355fba Removed unwanted newline. 2016-08-13 13:21:00 +02:00
c12be088c6 Updated change log with unified output format. 2016-08-13 11:12:38 +02:00
9c3cfe8f7b Dropped »meta« prefix of encoding file because there will only be meta encodings. 2016-08-13 11:10:29 +02:00
d4c168af30 Unified SAS and PDDL meta encodings. 2016-08-13 11:09:35 +02:00
f2d3aee662 Updated PDDL meta encoding to recent changes of output format. 2016-08-13 11:09:35 +02:00
340db244f6 Fixed bug in output format. 2016-08-13 04:04:28 +02:00
8969364f73 Fixed syntax error in output format. 2016-08-13 03:27:37 +02:00
b67168134b Made initial state definition consistent with unified output format. 2016-08-13 03:22:25 +02:00
97d33da686 Added effect ID as a placeholder (for conditional effects) for consistency with unified output format. 2016-08-13 03:17:48 +02:00
1f35bda3d2 Wrapped translated PDDL action definitions for usability in meta encodings. 2016-08-13 03:11:38 +02:00
6960e8a8c7 Wrapped translated PDDL constant definitions for usability in meta encodings. 2016-08-13 03:09:14 +02:00
b30cecd297 Turning translated PDDL predicates into unified variable format in rest of output format. 2016-08-13 03:08:05 +02:00
99fc6988a3 Renamed heading to »variables«. 2016-08-13 02:50:07 +02:00
cf022f9959 Started turning translated PDDL predicates into unified variable format. 2016-08-13 02:48:30 +02:00
0a1044743e Renamed meta predicate for simplicity. 2016-08-13 02:33:28 +02:00
94b204615b Wrapped translated PDDL type definitions for usability in meta encodings. 2016-08-13 02:32:27 +02:00
230c6dfc15 Made order of sections of translated SAS more uniform with PDDL. 2016-08-13 02:29:48 +02:00
8be67e7065 Updated SAS meta encoding to recent changes of output format. 2016-08-13 01:49:00 +02:00
378b2ae673 Wrapped translated SAS axiom rule definitions for usability in meta encodings. 2016-08-13 01:44:45 +02:00
36e517bd80 Wrapped translated SAS mutex group definitions for usability in meta encodings. 2016-08-13 01:42:18 +02:00
569b3d0c97 Wrapped translated SAS action definitions for usability in meta encodings. 2016-08-13 01:40:31 +02:00
daf68d24ab Added highlighting of variable names. 2016-08-13 01:39:49 +02:00
8a82f52100 Wrapped translated SAS variable definitions for usability in meta encodings. 2016-08-13 01:36:08 +02:00
d0864b9efe Extended parser tests. 2016-08-08 12:40:02 +02:00
18bd606262 Extended parser tests. 2016-08-07 16:46:48 +02:00
252f50108b Removed unnecessary file. 2016-08-07 16:22:26 +02:00
015c34fc2b Minor refactoring. 2016-08-03 00:33:20 +02:00
d7b47797df Made Stream members protected again. 2016-08-03 00:28:22 +02:00
544d4e0635 Major refactoring of underlying Parser class. 2016-08-02 20:33:49 +02:00
73c9d6c1f3 Checking that Parser initially is case-sensitive. 2016-06-22 09:14:01 +01:00
d9578b6f1c Testing Parser position with seek and advance. 2016-06-22 09:07:19 +01:00
b5e325cbee Testing Parser’s reset method. 2016-06-22 09:02:46 +01:00
234938349c Fixed incorrect seek positions. 2016-06-22 08:59:18 +01:00
9ed7277ec9 Fixed minor formatting issue with axiom rules. 2016-06-22 08:45:48 +01:00
dc87c09442 Merge branch 'master' of github.com:potassco/plasp into develop 2016-06-15 00:57:01 +02:00
00688765fd Fixed typos in readme file. 2016-06-15 00:56:17 +02:00
3702b72feb Version bump after release 3.0.1. 2016-06-15 00:18:09 +02:00
117 changed files with 3297 additions and 1370 deletions

View File

@@ -1,5 +1,19 @@
# Change Log
## 3.0.2 (2016-08-18)
Features:
* unified translation format for SAS and PDDL files
* documentation of `plasp`s output format
* improved output syntax highlighting
* uses ASP string literals to avoid escaping PDDL identifiers
Bug Fixes:
* fixes minor formatting issues in SAS translation
* fixes issue with unsupported expression negations
## 3.0.1 (2016-06-14)
Features:

View File

@@ -7,7 +7,7 @@ set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wpedantic")
set(CMAKE_CXX_FLAGS_DEBUG "-g")
add_definitions(-std=c++14)
option(BUILD_TESTS "Build unit tests" ON)
option(BUILD_TESTS "Build unit tests" OFF)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)

View File

@@ -6,8 +6,8 @@
`plasp` 3 is in early development and not intended for productive use yet.
`plasp` 3 translates planning problem instances to ASP facts.
`plasp` 3 supports the input languages [PDDL](https://helios.hud.ac.uk/scommv/IPC-14/software.html) (only basic features currently) and the [SAS](http://www.fast-downward.org/TranslatorOutputFormat) (full support of the current version 3), which is used by [Fast Downward](http://www.fast-downward.org/).
`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.
@@ -24,7 +24,7 @@ $ plasp domain.pddl problem.pddl
Alternatively, PDDL instances may first be translated to SAS, the output format of [Fast Downward](http://www.fast-downward.org/).
```bash
$ ./fast-downward.py --translate --build=release64 domain.pddl instance.pddl
$ ./fast-downward.py --translate --build=release64 domain.pddl problem.pddl
```
This creates a file called `output.sas`, which may now be translated by `plasp`.
@@ -42,51 +42,29 @@ $ plasp domain.pddl problem.pddl > instance.lp
$ clingo encodings/pddl-meta-sequential-incremental.lp instance.lp
```
### Command-Line Interface
## Command-Line Interface
```bash
$ plasp [files] [options]
```
`[files]` may be omitted, in which case the input is read from `std::cin`.
The `[options]` are listed below:
`plasp` automatically detects the language of the input program.
| **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`). |
See [command-line interface](doc/command-line-interface.md) for more details.
## Output Format
`plasp` provides a uniform output format for SAS and PDDL input problems.
See [output format](doc/output-format.md) for more details.
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
`plasp` requires a C++14 compiler (preferrably GCC ≥ 6.1 or clang ≥ 3.8), the `boost` libraries (≥ 1.55), and CMake for building.
`plasp` requires `boost` and is built via CMake and a C++ compiler.
```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`.
### 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
```
See [building instructions](doc/building-instructions.md) for more details.
## Contributors

View File

@@ -66,7 +66,7 @@ int main(int argc, char **argv)
if (variablesMap.count("version"))
{
std::cout << "plasp version 3.0.1" << std::endl;
std::cout << "plasp version 3.0.2" << std::endl;
return EXIT_SUCCESS;
}
@@ -104,9 +104,7 @@ int main(int argc, char **argv)
try
{
plasp::utils::Parser parser;
parser.setCaseSensitive(false);
plasp::utils::Parser<plasp::utils::CaseInsensitiveParserPolicy> parser;
if (variablesMap.count("input"))
{
@@ -115,11 +113,11 @@ int main(int argc, char **argv)
std::for_each(inputFiles.cbegin(), inputFiles.cend(),
[&](const auto &inputFile)
{
parser.readFile(inputFile);
parser.read(inputFile);
});
}
else
parser.readStream("std::cin", std::cin);
parser.read("std::cin", std::cin);
const auto detectLanguage =
[&]()

View File

@@ -0,0 +1,41 @@
# 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, enable the flag `BUILD_TESTS` in your CMake configuration.
Finally, build and run the tests as follows:
```bash
$ make run-tests
```

View 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`). |

View 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).
```

209
doc/output-format.md Normal file
View File

@@ -0,0 +1,209 @@
# 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 that <type 1> inherits <type 2>
inherits(type(<type 1>), type(<type 2>)).
% 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.
`plasp` automatically generates all matching `has` predicates for objects with types that inherit other types.
### 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, `plasp` sets all unspecified initial state variables to `false` in order to make the initial state total.
### 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>, effect(unconditional), <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.
The second argument of `postcondition`, `effect(unconditional)`, is not used and exists only for consistency with [actions](#actions).
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.

View File

@@ -1,31 +0,0 @@
#include <incmode>.
#program base.
% Establish initial state
holds(Predicate, 0) :- initialState(Predicate).
#program step(t).
% Perform actions
1 {occurs(action(Action), t) : action(Action)} 1.
% Check preconditions
:- occurs(Action, t), precondition(Action, Predicate, true), not holds(Predicate, t - 1).
:- occurs(Action, t), precondition(Action, Predicate, false), holds(Predicate, t - 1).
% Apply effects
caused(Predicate, true, t) :- occurs(Action, t), postcondition(Action, Predicate, true).
caused(Predicate, false, t) :- occurs(Action, t), postcondition(Action, Predicate, false).
holds(Predicate, t) :- caused(Predicate, true, t).
holds(Predicate, t) :- holds(Predicate, t - 1), not caused(Predicate, false, t).
#program check(t).
% Verify that goal is met
:- query(t), goal(Predicate, true), not holds(Predicate, t).
:- query(t), goal(Predicate, false), holds(Predicate, t).
#show query/1.
#show occurs/2.

View File

@@ -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.

View File

@@ -0,0 +1,40 @@
#include <incmode>.
% Check feature requirements
:- requires(feature(actionCosts)).
:- requires(feature(axiomRules)).
:- requires(feature(conditionalEffects)).
#program base.
% Establish initial state
holds(Variable, Value, 0) :- initialState(Variable, Value).
#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.

View File

@@ -13,15 +13,14 @@ namespace plasp
//
////////////////////////////////////////////////////////////////////////////////////////////////////
Language::Type detectLanguage(utils::Parser &parser)
Language::Type detectLanguage(utils::Parser<utils::CaseInsensitiveParserPolicy> &parser)
{
parser.setCaseSensitive(false);
parser.skipWhiteSpace();
// SAS begins with "begin_version"
if (parser.probe<std::string>("begin"))
if (parser.testAndSkip<std::string>("begin"))
{
parser.seek(std::ios::beg);
parser.seek(0);
return Language::Type::SAS;
}
@@ -33,7 +32,7 @@ Language::Type detectLanguage(utils::Parser &parser)
}
// PDDL contains sections starting with "(define"
if (parser.probe<std::string>("(") && parser.probe<std::string>("define"))
if (parser.testAndSkip<std::string>("(") && parser.testAndSkip<std::string>("define"))
{
parser.seek(std::ios::beg);
return Language::Type::PDDL;

View File

@@ -30,6 +30,8 @@ class Action
const Expression *precondition() const;
const Expression *effect() const;
void normalizeParameterNames();
private:
Action() = default;

View File

@@ -5,6 +5,7 @@
#include <unordered_map>
#include <vector>
#include <plasp/pddl/Parser.h>
#include <plasp/utils/Logger.h>
namespace plasp
@@ -22,20 +23,21 @@ class Context
{
public:
Context() = default;
~Context() = default;
explicit Context(utils::Parser &&parser)
: parser{std::move(parser)}
explicit Context(Parser &&otherParser)
: parser{std::move(otherParser)}
{
}
explicit Context(utils::Logger &&logger)
: logger{std::move(logger)}
explicit Context(utils::Logger &&otherLogger)
: logger{std::move(otherLogger)}
{
}
explicit Context(utils::Parser &&parser, utils::Logger &&logger)
: parser{std::move(parser)},
logger{std::move(logger)}
explicit Context(Parser &&otherParser, utils::Logger &&otherLogger)
: parser{std::move(otherParser)},
logger{std::move(otherLogger)}
{
}
@@ -56,7 +58,7 @@ class Context
return *this;
}
utils::Parser parser;
Parser parser;
utils::Logger logger;
};

View File

@@ -35,6 +35,8 @@ class Description
bool containsProblem() const;
const Problem &problem() const;
void normalizeParameterNames();
private:
Description();
@@ -45,9 +47,9 @@ class Description
Context m_context;
utils::Parser::Position m_domainPosition;
utils::Stream::Position m_domainPosition;
std::unique_ptr<Domain> m_domain;
utils::Parser::Position m_problemPosition;
utils::Stream::Position m_problemPosition;
std::unique_ptr<Problem> m_problem;
};

View File

@@ -4,10 +4,11 @@
#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>
#include <plasp/pddl/Requirement.h>
namespace plasp
{
@@ -34,7 +35,7 @@ class Domain
const Requirements &requirements() const;
bool hasRequirement(Requirement::Type requirementType) const;
void checkRequirement(Requirement::Type requirementType) const;
void checkRequirement(Requirement::Type requirementType);
expressions::PrimitiveTypes &types();
const expressions::PrimitiveTypes &types() const;
@@ -50,6 +51,8 @@ class Domain
void checkConsistency();
void normalizeParameterNames();
private:
void parseSection();
@@ -68,19 +71,19 @@ class Domain
std::string m_name;
utils::Parser::Position m_requirementsPosition;
utils::Stream::Position m_requirementsPosition;
Requirements m_requirements;
utils::Parser::Position m_typesPosition;
utils::Stream::Position m_typesPosition;
expressions::PrimitiveTypes m_types;
utils::Parser::Position m_constantsPosition;
utils::Stream::Position m_constantsPosition;
expressions::Constants m_constants;
utils::Parser::Position m_predicatesPosition;
utils::Stream::Position m_predicatesPosition;
expressions::PredicateDeclarations m_predicates;
std::vector<utils::Parser::Position> m_actionPositions;
std::vector<utils::Stream::Position> m_actionPositions;
std::vector<std::unique_ptr<Action>> m_actions;
};

View File

@@ -3,7 +3,7 @@
#include <iostream>
#include <plasp/utils/Parser.h>
#include <plasp/pddl/Parser.h>
namespace plasp
{
@@ -16,7 +16,7 @@ namespace pddl
//
////////////////////////////////////////////////////////////////////////////////////////////////////
inline void skipSection(utils::Parser &parser)
inline void skipSection(Parser &parser)
{
size_t openParentheses = 1;

View 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

View File

@@ -4,6 +4,7 @@
#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
@@ -32,7 +33,7 @@ class Problem
const Requirements &requirements() const;
bool hasRequirement(Requirement::Type requirementType) const;
void checkRequirement(Requirement::Type requirementType) const;
void checkRequirement(Requirement::Type requirementType);
expressions::Constants &objects();
const expressions::Constants &objects() const;
@@ -61,18 +62,18 @@ class Problem
std::string m_name;
utils::Parser::Position m_domainPosition;
utils::Stream::Position m_domainPosition;
utils::Parser::Position m_requirementsPosition;
utils::Stream::Position m_requirementsPosition;
Requirements m_requirements;
utils::Parser::Position m_objectsPosition;
utils::Stream::Position m_objectsPosition;
expressions::Constants m_objects;
utils::Parser::Position m_initialStatePosition;
utils::Stream::Position m_initialStatePosition;
std::unique_ptr<InitialState> m_initialState;
utils::Parser::Position m_goalPosition;
utils::Stream::Position m_goalPosition;
ExpressionPointer m_goal;
};

View File

@@ -19,7 +19,7 @@ namespace pddl
class TranslatorASP
{
public:
explicit TranslatorASP(const Description &description, utils::LogStream &outputStream);
explicit TranslatorASP(Description &description, utils::LogStream &outputStream);
void translate() const;
@@ -39,7 +39,7 @@ class TranslatorASP
void translateLiteral(const Expression &literal) const;
void translatePredicate(const expressions::Predicate &predicate) const;
const Description &m_description;
Description &m_description;
utils::LogStream &m_outputStream;
};

View File

@@ -3,7 +3,6 @@
#include <plasp/pddl/Context.h>
#include <plasp/pddl/Expression.h>
#include <plasp/pddl/Identifier.h>
namespace plasp
{
@@ -57,8 +56,8 @@ AtPointer At::parse(Context &context, ExpressionContext &expressionContext,
const auto position = parser.position();
if (!parser.probe<std::string>("(")
|| !parser.probeIdentifier("at", isIdentifier))
if (!parser.testAndSkip<std::string>("(")
|| !parser.testIdentifierAndSkip("at"))
{
parser.seek(position);
return nullptr;
@@ -68,9 +67,9 @@ AtPointer At::parse(Context &context, ExpressionContext &expressionContext,
const auto timePointPosition = parser.position();
if (parser.probeIdentifier("start", isIdentifier))
if (parser.testIdentifierAndSkip("start"))
timePoint = TimePointStart;
else if (parser.probeIdentifier("end", isIdentifier))
else if (parser.testIdentifierAndSkip("end"))
timePoint = TimePointEnd;
else if (parser.probeNumber())
{

View File

@@ -4,7 +4,6 @@
#include <plasp/pddl/ConsistencyException.h>
#include <plasp/pddl/Context.h>
#include <plasp/pddl/Expression.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/pddl/expressions/Variable.h>
namespace plasp
@@ -52,8 +51,8 @@ std::unique_ptr<Derived> Binary<Derived>::parse(Context &context,
const auto position = parser.position();
if (!parser.probe<std::string>("(")
|| !parser.probeIdentifier(Derived::Identifier, isIdentifier))
if (!parser.testAndSkip<std::string>("(")
|| !parser.testIdentifierAndSkip(Derived::Identifier))
{
parser.seek(position);
return nullptr;

View File

@@ -2,7 +2,6 @@
#define __PLASP__PDDL__EXPRESSIONS__CONSTANT_H
#include <plasp/pddl/Expression.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/utils/Parser.h>
#include <plasp/utils/ParserException.h>

View File

@@ -4,7 +4,6 @@
#include <plasp/pddl/ConsistencyException.h>
#include <plasp/pddl/Context.h>
#include <plasp/pddl/Expression.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/pddl/expressions/Variable.h>
namespace plasp
@@ -50,8 +49,8 @@ std::unique_ptr<Derived> NAry<Derived>::parse(Context &context,
const auto position = parser.position();
if (!parser.probe<std::string>("(")
|| !parser.probeIdentifier(Derived::Identifier, isIdentifier))
if (!parser.testAndSkip<std::string>("(")
|| !parser.testIdentifierAndSkip(Derived::Identifier))
{
parser.seek(position);
return nullptr;
@@ -71,7 +70,7 @@ std::unique_ptr<Derived> NAry<Derived>::parse(Context &context,
}
if (expression->m_arguments.empty())
context.logger.logWarning(context.parser, "" + Derived::Identifier + "” expressions should not be empty");
context.logger.logWarning(parser.coordinate(), "" + Derived::Identifier + "” expressions should not be empty");
parser.expect<std::string>(")");

View File

@@ -3,7 +3,6 @@
#include <plasp/pddl/Context.h>
#include <plasp/pddl/Expression.h>
#include <plasp/pddl/Identifier.h>
namespace plasp
{
@@ -50,8 +49,8 @@ NotPointer Not::parse(Context &context, ExpressionContext &expressionContext,
const auto position = parser.position();
if (!parser.probe<std::string>("(")
|| !parser.probeIdentifier("not", isIdentifier))
if (!parser.testAndSkip<std::string>("(")
|| !parser.testIdentifierAndSkip("not"))
{
parser.seek(position);
return nullptr;

View File

@@ -29,6 +29,8 @@ class PredicateDeclaration: public ExpressionCRTP<PredicateDeclaration>
bool isDeclared() const;
void normalizeParameterNames();
private:
PredicateDeclaration();

View File

@@ -3,7 +3,6 @@
#include <plasp/pddl/ConsistencyException.h>
#include <plasp/pddl/Expression.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/utils/ParserException.h>
namespace plasp

View File

@@ -28,7 +28,9 @@ class Variable: public ExpressionCRTP<Variable>
const ExpressionContext &expressionContext);
public:
void setName(std::string name);
const std::string &name() const;
const Expression *type() const;
void setDirty(bool isDirty = true);

View File

@@ -27,8 +27,8 @@ using AssignedVariables = std::vector<AssignedVariable>;
class AssignedVariable
{
public:
static AssignedVariable fromSAS(utils::Parser &parser, const Variables &variables);
static AssignedVariable fromSAS(utils::Parser &parser, const Variable &variable);
static AssignedVariable fromSAS(utils::Parser<> &parser, const Variables &variables);
static AssignedVariable fromSAS(utils::Parser<> &parser, const Variable &variable);
public:
explicit AssignedVariable(const Variable &variable, const Value &value);

View File

@@ -29,7 +29,7 @@ class AxiomRule
using Condition = AssignedVariable;
using Conditions = AssignedVariables;
static AxiomRule fromSAS(utils::Parser &parser, const Variables &variables);
static AxiomRule fromSAS(utils::Parser<> &parser, const Variables &variables);
public:
const Conditions &conditions() const;

View File

@@ -29,7 +29,7 @@ namespace sas
class Description
{
public:
static Description fromParser(utils::Parser &&parser);
static Description fromParser(utils::Parser<> &&parser);
static Description fromStream(std::istream &istream);
static Description fromFile(const boost::filesystem::path &path);
@@ -45,19 +45,21 @@ class Description
bool usesAxiomRules() const;
bool usesConditionalEffects() const;
bool hasRequirements() const;
private:
Description();
void parseContent(utils::Parser &parser);
void parseContent(utils::Parser<> &parser);
void parseVersionSection(utils::Parser &parser) const;
void parseMetricSection(utils::Parser &parser);
void parseVariablesSection(utils::Parser &parser);
void parseMutexSection(utils::Parser &parser);
void parseInitialStateSection(utils::Parser &parser);
void parseGoalSection(utils::Parser &parser);
void parseOperatorSection(utils::Parser &parser);
void parseAxiomSection(utils::Parser &parser);
void parseVersionSection(utils::Parser<> &parser) const;
void parseMetricSection(utils::Parser<> &parser);
void parseVariablesSection(utils::Parser<> &parser);
void parseMutexSection(utils::Parser<> &parser);
void parseInitialStateSection(utils::Parser<> &parser);
void parseGoalSection(utils::Parser<> &parser);
void parseOperatorSection(utils::Parser<> &parser);
void parseAxiomSection(utils::Parser<> &parser);
bool m_usesActionCosts;

View File

@@ -29,7 +29,7 @@ class Effect
using Condition = AssignedVariable;
using Conditions = AssignedVariables;
static Effect fromSAS(utils::Parser &parser, const Variables &variables, Conditions &preconditions);
static Effect fromSAS(utils::Parser<> &parser, const Variables &variables, Conditions &preconditions);
public:
const Conditions &conditions() const;

View File

@@ -21,7 +21,7 @@ class Goal
using Fact = AssignedVariable;
using Facts = AssignedVariables;
static Goal fromSAS(utils::Parser &parser, const Variables &variables);
static Goal fromSAS(utils::Parser<> &parser, const Variables &variables);
public:
const Facts &facts() const;

View File

@@ -21,7 +21,7 @@ class InitialState
using Fact = AssignedVariable;
using Facts = AssignedVariables;
static InitialState fromSAS(utils::Parser &parser, const Variables &variables);
static InitialState fromSAS(utils::Parser<> &parser, const Variables &variables);
public:
const Facts &facts() const;

View File

@@ -28,7 +28,7 @@ class MutexGroup
using Fact = AssignedVariable;
using Facts = AssignedVariables;
static MutexGroup fromSAS(utils::Parser &parser, const Variables &variables);
static MutexGroup fromSAS(utils::Parser<> &parser, const Variables &variables);
public:
const Facts &facts() const;

View File

@@ -33,7 +33,7 @@ class Operator
using Condition = AssignedVariable;
using Conditions = AssignedVariables;
static Operator fromSAS(utils::Parser &parser, const Variables &variables);
static Operator fromSAS(utils::Parser<> &parser, const Variables &variables);
public:
void printPredicateAsASP(utils::LogStream &ostream) const;

View File

@@ -22,7 +22,7 @@ namespace sas
class Predicate
{
public:
static Predicate fromSAS(utils::Parser &parser);
static Predicate fromSAS(utils::Parser<> &parser);
using Arguments = std::vector<std::string>;

View File

@@ -39,14 +39,13 @@ struct Value
static const Value Any;
static const Value None;
static Value fromSAS(utils::Parser &parser);
static const Value &referenceFromSAS(utils::Parser &parser, const Variable &variable);
static Value fromSAS(utils::Parser<> &parser);
static const Value &referenceFromSAS(utils::Parser<> &parser, const Variable &variable);
public:
Value negated() const;
void printAsSAS(utils::LogStream &outputStream) const;
void printAsASP(utils::LogStream &outputStream) const;
void printAsASPPredicate(utils::LogStream &outputStream) const;
Sign sign() const;

View File

@@ -28,8 +28,8 @@ using Variables = std::vector<Variable>;
class Variable
{
public:
static Variable fromSAS(utils::Parser &parser);
static const Variable &referenceFromSAS(utils::Parser &parser, const Variables &variables);
static Variable fromSAS(utils::Parser<> &parser);
static const Variable &referenceFromSAS(utils::Parser<> &parser, const Variables &variables);
public:
void printNameAsASPPredicate(utils::LogStream &outputStream) const;

View File

@@ -26,7 +26,7 @@ using VariableTransitions = std::vector<VariableTransition>;
class VariableTransition
{
public:
static VariableTransition fromSAS(utils::Parser &parser, const Variables &variables);
static VariableTransition fromSAS(utils::Parser<> &parser, const Variables &variables);
public:
const Variable &variable() const;

View File

@@ -93,6 +93,26 @@ struct Token
////////////////////////////////////////////////////////////////////////////////////////////////////
struct RuleName: public Token
{
RuleName(const std::string &name)
: Token(name)
{
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////
inline LogStream &operator<<(LogStream &stream, const RuleName &keyword)
{
return (stream
<< utils::Format(utils::Color::White, utils::FontWeight::Bold)
<< keyword.name
<< utils::ResetFormat());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Keyword: public Token
{
Keyword(const std::string &name)
@@ -106,11 +126,10 @@ struct Keyword: public Token
inline LogStream &operator<<(LogStream &stream, const Keyword &keyword)
{
return (stream
<< utils::Format(utils::Color::White, utils::FontWeight::Bold)
<< utils::Format(utils::Color::Blue, utils::FontWeight::Normal)
<< keyword.name
<< utils::ResetFormat());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Number: public Token
@@ -126,7 +145,7 @@ struct Number: public Token
inline LogStream &operator<<(LogStream &stream, const Number &number)
{
return (stream
<< utils::Format(utils::Color::Yellow, utils::FontWeight::Bold)
<< utils::Format(utils::Color::Yellow, utils::FontWeight::Normal)
<< number.name
<< utils::ResetFormat());
}
@@ -153,6 +172,66 @@ inline LogStream &operator<<(LogStream &stream, const Variable &variable)
////////////////////////////////////////////////////////////////////////////////////////////////////
struct String: public Token
{
String(const std::string &name)
: Token(name)
{
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////
inline LogStream &operator<<(LogStream &stream, const String &string)
{
return (stream
<< utils::Format(utils::Color::Green, utils::FontWeight::Normal)
<< "\"" << string.name << "\""
<< utils::ResetFormat());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Boolean: public Token
{
Boolean(const std::string &name)
: Token(name)
{
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////
inline LogStream &operator<<(LogStream &stream, const Boolean &string)
{
return (stream
<< utils::Format(utils::Color::Red, utils::FontWeight::Normal)
<< string.name
<< utils::ResetFormat());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Reserved: public Token
{
Reserved(const std::string &name)
: Token(name)
{
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////
inline LogStream &operator<<(LogStream &stream, const Reserved &string)
{
return (stream
<< utils::Format(utils::Color::White, utils::FontWeight::Normal)
<< string.name
<< utils::ResetFormat());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Heading1: public Token
{
Heading1(const std::string &name)

View File

@@ -1,57 +0,0 @@
#ifndef __PLASP__UTILS__IO_H
#define __PLASP__UTILS__IO_H
#include <boost/algorithm/string/replace.hpp>
namespace plasp
{
namespace utils
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// IO
//
////////////////////////////////////////////////////////////////////////////////////////////////////
inline std::string escapeASP(const std::string &string)
{
auto escaped = string;
boost::replace_all(escaped, "_", "__");
boost::replace_all(escaped, "-", "_h");
boost::replace_all(escaped, "@", "_a");
return escaped;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline std::string unescapeASP(const std::string &string)
{
auto unescaped = string;
boost::replace_all(unescaped, "_a", "@");
boost::replace_all(unescaped, "_h", "-");
boost::replace_all(unescaped, "__", "_");
return unescaped;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline std::string escapeASPVariable(const std::string &string)
{
auto escaped = escapeASP(string);
escaped.front() = std::toupper(escaped.front());
return escaped;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif

View File

@@ -118,11 +118,17 @@ class LogStream
inline LogStream &operator<<(bool value);
inline LogStream &operator<<(const void *value);
inline LogStream &operator<<(const char *value);
inline LogStream &operator<<(const signed char *value);
inline LogStream &operator<<(const unsigned char *value);
inline LogStream &operator<<(std::basic_streambuf<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> &));
inline LogStream &operator<<(char value);
inline LogStream &operator<<(signed char value);
inline LogStream &operator<<(unsigned char value);
private:
StandardStream m_standardStream;
ColorPolicy m_colorPolicy;
@@ -242,6 +248,22 @@ LogStream &LogStream::operator<<(const char *value)
////////////////////////////////////////////////////////////////////////////////////////////////////
LogStream &LogStream::operator<<(const signed char *value)
{
ostream() << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
LogStream &LogStream::operator<<(const unsigned char *value)
{
ostream() << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
LogStream &LogStream::operator<<(std::basic_streambuf<CharacterType, TraitsType>* sb)
{
ostream() << sb;
@@ -283,6 +305,30 @@ inline LogStream &operator<<(LogStream &stream, const std::basic_string<Characte
////////////////////////////////////////////////////////////////////////////////////////////////////
LogStream &LogStream::operator<<(char value)
{
ostream() << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
LogStream &LogStream::operator<<(signed char value)
{
ostream() << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
LogStream &LogStream::operator<<(unsigned char value)
{
ostream() << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@@ -4,8 +4,8 @@
#include <string>
#include <plasp/utils/LogStream.h>
#include <plasp/utils/Parser.h>
#include <plasp/utils/ParserException.h>
#include <plasp/utils/StreamCoordinate.h>
namespace plasp
{
@@ -44,8 +44,8 @@ class Logger
void setColorPolicy(LogStream::ColorPolicy colorPolicy);
void logError(const std::string &message);
void logError(const Parser::Coordinate &coordinate, const std::string &message);
void logWarning(const Parser &parser, const std::string &message);
void logError(const StreamCoordinate &coordinate, const std::string &message);
void logWarning(const StreamCoordinate &parserCoordinate, const std::string &message);
private:
LogStream m_outputStream;

View File

@@ -8,111 +8,194 @@
#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
//
////////////////////////////////////////////////////////////////////////////////////////////////////
class Parser
template<class ParserPolicy = CaseSensitiveParserPolicy>
class Parser: public Stream, public ParserPolicy
{
public:
using Position = std::stringstream::pos_type;
struct Coordinate
{
std::string sectionName;
size_t row;
size_t column;
};
struct StreamDelimiter
{
Position position;
std::string sectionName;
};
template<class OtherParserPolicy>
friend class Parser;
public:
explicit Parser();
explicit Parser(std::string streamName, std::istream &istream);
// Forbid copy construction/assignment
Parser(const Parser &other) = delete;
Parser &operator=(const Parser &other) = delete;
Parser(Parser &&other);
Parser &operator=(Parser &&other);
void readStream(std::string streamName, std::istream &istream);
void readFile(const boost::filesystem::path &path);
void reset();
void seek(Position position);
Position position() const;
Coordinate coordinate() const;
void setCaseSensitive(bool isCaseInsensitive = true);
char currentCharacter() const;
void advance();
bool atEndOfStream() const;
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<class CharacterPredicate, class WhiteSpacePredicate>
std::string parseIdentifier(CharacterPredicate characterPredicate, WhiteSpacePredicate whiteSpacePredicate);
template<class CharacterPredicate>
std::string parseIdentifier(CharacterPredicate characterPredicate);
template<typename Type>
bool testAndReturn(const Type &expectedValue);
template<typename Type>
bool probe(const Type &expectedValue);
template<class CharacterPredicate>
bool probeIdentifier(const std::string &identifier, CharacterPredicate characterPredicate);
bool probeNumber();
bool testAndSkip(const Type &expectedValue);
template<typename Type>
void expect(const Type &expectedValue);
template<class WhiteSpacePredicate>
void skipWhiteSpace(WhiteSpacePredicate whiteSpacePredicate);
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();
std::string getLine();
private:
static const std::istreambuf_iterator<char> EndOfFile;
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>);
private:
void checkStream() const;
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();
mutable std::stringstream m_stream;
std::vector<StreamDelimiter> m_streamDelimiters;
bool m_isCaseSensitive;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class CharacterPredicate, class WhiteSpacePredicate>
std::string Parser::parseIdentifier(CharacterPredicate characterPredicate, WhiteSpacePredicate whiteSpacePredicate)
template<class ParserPolicy>
Parser<ParserPolicy>::Parser()
: Stream()
{
skipWhiteSpace(whiteSpacePredicate);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
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;
@@ -120,7 +203,7 @@ std::string Parser::parseIdentifier(CharacterPredicate characterPredicate, White
{
const auto character = currentCharacter();
if (!characterPredicate(character))
if (!ParserPolicy::isIdentifierCharacter(character))
return value;
value.push_back(character);
@@ -130,33 +213,342 @@ std::string Parser::parseIdentifier(CharacterPredicate characterPredicate, White
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class CharacterPredicate>
std::string Parser::parseIdentifier(CharacterPredicate characterPredicate)
template<class ParserPolicy>
bool Parser<ParserPolicy>::testIdentifierAndSkip(const std::string &expectedValue)
{
return parseIdentifier(characterPredicate,
[&](const auto character)
{
return std::isspace(character);
});
return testAndSkip(expectedValue) && !ParserPolicy::isIdentifierCharacter(currentCharacter());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class CharacterPredicate>
bool Parser::probeIdentifier(const std::string &expectedValue, CharacterPredicate characterPredicate)
template<class ParserPolicy>
bool Parser<ParserPolicy>::probeNumber()
{
return probe<std::string>(expectedValue) && !characterPredicate(currentCharacter());
const auto previousPosition = position();
skipWhiteSpace();
while (!ParserPolicy::isWhiteSpaceCharacter(currentCharacter()))
if (!std::isdigit(currentCharacter()))
{
seek(previousPosition);
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class WhiteSpacePredicate>
void Parser::skipWhiteSpace(WhiteSpacePredicate whiteSpacePredicate)
template<class ParserPolicy>
std::string Parser<ParserPolicy>::parseLine()
{
checkStream();
std::string value;
while (!atEndOfStream() && whiteSpacePredicate(currentCharacter()))
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);
}
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -4,7 +4,7 @@
#include <exception>
#include <string>
#include <plasp/utils/Parser.h>
#include <plasp/utils/StreamCoordinate.h>
namespace plasp
{
@@ -20,18 +20,18 @@ namespace utils
class ParserException: public std::exception
{
public:
explicit ParserException(const utils::Parser &parser)
: ParserException(parser, "unspecified parser error")
explicit ParserException(const StreamCoordinate &coordinate)
: ParserException(coordinate, "unspecified parser error")
{
}
explicit ParserException(const utils::Parser &parser, const char *message)
: ParserException(parser, static_cast<std::string>(message))
explicit ParserException(const StreamCoordinate &coordinate, const char *message)
: ParserException(coordinate, static_cast<std::string>(message))
{
}
explicit ParserException(const utils::Parser &parser, const std::string &message)
: m_coordinate{parser.coordinate()},
explicit ParserException(const StreamCoordinate &coordinate, const std::string &message)
: m_coordinate{coordinate},
m_message{message},
m_plainMessage{m_coordinate.sectionName + ":" + std::to_string(m_coordinate.row)
+ ":" + std::to_string(m_coordinate.column) + " " + m_message}
@@ -47,7 +47,7 @@ class ParserException: public std::exception
return m_plainMessage.c_str();
}
const Parser::Coordinate &coordinate() const
const StreamCoordinate &coordinate() const
{
return m_coordinate;
}
@@ -58,7 +58,7 @@ class ParserException: public std::exception
}
private:
Parser::Coordinate m_coordinate;
StreamCoordinate m_coordinate;
std::string m_message;
std::string m_plainMessage;
};

View 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

View 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

View File

@@ -1,27 +1,24 @@
#ifndef __PLASP__PDDL__IDENTIFIER_H
#define __PLASP__PDDL__IDENTIFIER_H
#ifndef __PLASP__UTILS__STREAM_COORDINATE_H
#define __PLASP__UTILS__STREAM_COORDINATE_H
#include <cctype>
#include <string>
namespace plasp
{
namespace pddl
namespace utils
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Identifier
// StreamCoordinate
//
////////////////////////////////////////////////////////////////////////////////////////////////////
const auto isIdentifier =
[](const auto character)
struct StreamCoordinate
{
return character != '?'
&& character != '('
&& character != ')'
&& character != ';'
&& std::isgraph(character);
std::string sectionName;
size_t row;
size_t column;
};
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,34 @@
(define (domain gripper-strips)
(:predicates (room ?r)
(ball ?b)
(gripper ?g)
(at-robby ?r)
(at ?b ?r)
(free ?g)
(carry ?o ?g))
(:action move
:parameters (?from ?to)
:precondition (and (room ?from) (room ?to) (at-robby ?from))
:effect (and (at-robby ?to)
(not (at-robby ?from))))
(:action pick
:parameters (?obj ?room ?gripper)
:precondition (and (ball ?obj) (room ?room) (gripper ?gripper)
(at ?obj ?room) (at-robby ?room) (free ?gripper))
:effect (and (carry ?obj ?gripper)
(not (at ?obj ?room))
(not (free ?gripper))))
(:action drop
:parameters (?obj ?room ?gripper)
:precondition (and (ball ?obj) (room ?room) (gripper ?gripper)
(carry ?obj ?gripper) (at-robby ?room))
:effect (and (at ?obj ?room)
(free ?gripper)
(not (carry ?obj ?gripper)))))

View File

@@ -0,0 +1,22 @@
(define (problem strips-gripper-x-1)
(:domain gripper-strips)
(:objects rooma roomb ball4 ball3 ball2 ball1 left right)
(:init (room rooma)
(room roomb)
(ball ball4)
(ball ball3)
(ball ball2)
(ball ball1)
(at-robby rooma)
(free left)
(free right)
(at ball4 rooma)
(at ball3 rooma)
(at ball2 rooma)
(at ball1 rooma)
(gripper left)
(gripper right))
(:goal (and (at ball4 roomb)
(at ball3 roomb)
(at ball2 roomb)
(at ball1 roomb))))

View File

@@ -0,0 +1,28 @@
(define (problem strips-gripper-x-2)
(:domain gripper-strips)
(:objects rooma roomb ball6 ball5 ball4 ball3 ball2 ball1 left right)
(:init (room rooma)
(room roomb)
(ball ball6)
(ball ball5)
(ball ball4)
(ball ball3)
(ball ball2)
(ball ball1)
(at-robby rooma)
(free left)
(free right)
(at ball6 rooma)
(at ball5 rooma)
(at ball4 rooma)
(at ball3 rooma)
(at ball2 rooma)
(at ball1 rooma)
(gripper left)
(gripper right))
(:goal (and (at ball6 roomb)
(at ball5 roomb)
(at ball4 roomb)
(at ball3 roomb)
(at ball2 roomb)
(at ball1 roomb))))

View File

@@ -0,0 +1,4 @@
instance | minimal horizon | #solutions with minimal horizon
============================================================
problem-01.pddl | 11 | 384
problem-02.pddl | 17 | 46080

View File

@@ -0,0 +1,49 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; 4 Op-blocks world
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (domain BLOCKS)
(:requirements :strips :typing)
(:types block)
(:predicates (on ?x - block ?y - block)
(ontable ?x - block)
(clear ?x - block)
(handempty)
(holding ?x - block)
)
(:action pick-up
:parameters (?x - block)
:precondition (and (clear ?x) (ontable ?x) (handempty))
:effect
(and (not (ontable ?x))
(not (clear ?x))
(not (handempty))
(holding ?x)))
(:action put-down
:parameters (?x - block)
:precondition (holding ?x)
:effect
(and (not (holding ?x))
(clear ?x)
(handempty)
(ontable ?x)))
(:action stack
:parameters (?x - block ?y - block)
:precondition (and (holding ?x) (clear ?y))
:effect
(and (not (holding ?x))
(not (clear ?y))
(clear ?x)
(handempty)
(on ?x ?y)))
(:action unstack
:parameters (?x - block ?y - block)
:precondition (and (on ?x ?y) (clear ?x) (handempty))
:effect
(and (holding ?x)
(clear ?y)
(not (clear ?x))
(not (handempty))
(not (on ?x ?y)))))

View File

@@ -0,0 +1,7 @@
(define (problem BLOCKS-4-0)
(:domain BLOCKS)
(:objects D B A C - block)
(:INIT (CLEAR C) (CLEAR A) (CLEAR B) (CLEAR D) (ONTABLE C) (ONTABLE A)
(ONTABLE B) (ONTABLE D) (HANDEMPTY))
(:goal (AND (ON D C) (ON C B) (ON B A)))
)

View File

@@ -0,0 +1,7 @@
(define (problem BLOCKS-5-1)
(:domain BLOCKS)
(:objects A D C E B - block)
(:INIT (CLEAR B) (CLEAR E) (CLEAR C) (ONTABLE D) (ONTABLE E) (ONTABLE C)
(ON B A) (ON A D) (HANDEMPTY))
(:goal (AND (ON D C) (ON C B) (ON B A) (ON A E)))
)

View File

@@ -0,0 +1,7 @@
(define (problem BLOCKS-8-1)
(:domain BLOCKS)
(:objects B A G C F D H E - block)
(:INIT (CLEAR E) (CLEAR H) (CLEAR D) (CLEAR F) (ONTABLE C) (ONTABLE G)
(ONTABLE D) (ONTABLE F) (ON E C) (ON H A) (ON A B) (ON B G) (HANDEMPTY))
(:goal (AND (ON C D) (ON D B) (ON B G) (ON G F) (ON F H) (ON H A) (ON A E)))
)

View File

@@ -0,0 +1,8 @@
(define (problem BLOCKS-9-2)
(:domain BLOCKS)
(:objects B I C E D A G F H - block)
(:INIT (CLEAR H) (CLEAR F) (ONTABLE G) (ONTABLE F) (ON H A) (ON A D) (ON D E)
(ON E C) (ON C I) (ON I B) (ON B G) (HANDEMPTY))
(:goal (AND (ON F G) (ON G H) (ON H D) (ON D I) (ON I E) (ON E B) (ON B C)
(ON C A)))
)

View File

@@ -0,0 +1,6 @@
instance | minimal horizon | #solutions with minimal horizon
============================================================
problem-04-00.pddl | 6 | 1
problem-05-01.pddl | 10 | 2
problem-08-01.pddl | 20 | 60
problem-09-02.pddl | 20 | 37

View File

@@ -0,0 +1,66 @@
(define (domain miconic)
(:requirements :strips)
(:types passenger - object
floor - object
)
(:predicates
(origin ?person - passenger ?floor - floor)
;; entry of ?person is ?floor
;; inertia
(destin ?person - passenger ?floor - floor)
;; exit of ?person is ?floor
;; inertia
(above ?floor1 - floor ?floor2 - floor)
;; ?floor2 is located above of ?floor1
(boarded ?person - passenger)
;; true if ?person has boarded the lift
(not-boarded ?person - passenger)
;; true if ?person has not boarded the lift
(served ?person - passenger)
;; true if ?person has alighted as her destination
(not-served ?person - passenger)
;; true if ?person is not at their destination
(lift-at ?floor - floor)
;; current position of the lift is at ?floor
)
;;stop and allow boarding
(:action board
:parameters (?f - floor ?p - passenger)
:precondition (and (lift-at ?f) (origin ?p ?f))
:effect (boarded ?p))
(:action depart
:parameters (?f - floor ?p - passenger)
:precondition (and (lift-at ?f) (destin ?p ?f)
(boarded ?p))
:effect (and (not (boarded ?p))
(served ?p)))
;;drive up
(:action up
:parameters (?f1 - floor ?f2 - floor)
:precondition (and (lift-at ?f1) (above ?f1 ?f2))
:effect (and (lift-at ?f2) (not (lift-at ?f1))))
;;drive down
(:action down
:parameters (?f1 - floor ?f2 - floor)
:precondition (and (lift-at ?f1) (above ?f2 ?f1))
:effect (and (lift-at ?f2) (not (lift-at ?f1))))
)

View File

@@ -0,0 +1,58 @@
(define (problem mixed-f6-p3-u0-v0-g0-a0-n0-A0-B0-N0-F0-r0)
(:domain miconic)
(:objects p0 p1 p2 - passenger
f0 f1 f2 f3 f4 f5 - floor)
(:init
(above f0 f1)
(above f0 f2)
(above f0 f3)
(above f0 f4)
(above f0 f5)
(above f1 f2)
(above f1 f3)
(above f1 f4)
(above f1 f5)
(above f2 f3)
(above f2 f4)
(above f2 f5)
(above f3 f4)
(above f3 f5)
(above f4 f5)
(origin p0 f1)
(destin p0 f4)
(origin p1 f3)
(destin p1 f1)
(origin p2 f5)
(destin p2 f1)
(lift-at f0)
)
(:goal (and
(served p0)
(served p1)
(served p2)
))
)

View File

@@ -0,0 +1,58 @@
(define (problem mixed-f6-p3-u0-v0-g0-a0-n0-A0-B0-N0-F0-r1)
(:domain miconic)
(:objects p0 p1 p2 - passenger
f0 f1 f2 f3 f4 f5 - floor)
(:init
(above f0 f1)
(above f0 f2)
(above f0 f3)
(above f0 f4)
(above f0 f5)
(above f1 f2)
(above f1 f3)
(above f1 f4)
(above f1 f5)
(above f2 f3)
(above f2 f4)
(above f2 f5)
(above f3 f4)
(above f3 f5)
(above f4 f5)
(origin p0 f2)
(destin p0 f5)
(origin p1 f5)
(destin p1 f2)
(origin p2 f4)
(destin p2 f1)
(lift-at f0)
)
(:goal (and
(served p0)
(served p1)
(served p2)
))
)

View File

@@ -0,0 +1,77 @@
(define (problem mixed-f8-p4-u0-v0-g0-a0-n0-A0-B0-N0-F0-r0)
(:domain miconic)
(:objects p0 p1 p2 p3 - passenger
f0 f1 f2 f3 f4 f5 f6 f7 - floor)
(:init
(above f0 f1)
(above f0 f2)
(above f0 f3)
(above f0 f4)
(above f0 f5)
(above f0 f6)
(above f0 f7)
(above f1 f2)
(above f1 f3)
(above f1 f4)
(above f1 f5)
(above f1 f6)
(above f1 f7)
(above f2 f3)
(above f2 f4)
(above f2 f5)
(above f2 f6)
(above f2 f7)
(above f3 f4)
(above f3 f5)
(above f3 f6)
(above f3 f7)
(above f4 f5)
(above f4 f6)
(above f4 f7)
(above f5 f6)
(above f5 f7)
(above f6 f7)
(origin p0 f7)
(destin p0 f6)
(origin p1 f1)
(destin p1 f3)
(origin p2 f1)
(destin p2 f7)
(origin p3 f2)
(destin p3 f4)
(lift-at f0)
)
(:goal (and
(served p0)
(served p1)
(served p2)
(served p3)
))
)

View File

@@ -0,0 +1,77 @@
(define (problem mixed-f8-p4-u0-v0-g0-a0-n0-A0-B0-N0-F0-r1)
(:domain miconic)
(:objects p0 p1 p2 p3 - passenger
f0 f1 f2 f3 f4 f5 f6 f7 - floor)
(:init
(above f0 f1)
(above f0 f2)
(above f0 f3)
(above f0 f4)
(above f0 f5)
(above f0 f6)
(above f0 f7)
(above f1 f2)
(above f1 f3)
(above f1 f4)
(above f1 f5)
(above f1 f6)
(above f1 f7)
(above f2 f3)
(above f2 f4)
(above f2 f5)
(above f2 f6)
(above f2 f7)
(above f3 f4)
(above f3 f5)
(above f3 f6)
(above f3 f7)
(above f4 f5)
(above f4 f6)
(above f4 f7)
(above f5 f6)
(above f5 f7)
(above f6 f7)
(origin p0 f0)
(destin p0 f5)
(origin p1 f7)
(destin p1 f4)
(origin p2 f0)
(destin p2 f7)
(origin p3 f1)
(destin p3 f6)
(lift-at f0)
)
(:goal (and
(served p0)
(served p1)
(served p2)
(served p3)
))
)

View File

@@ -0,0 +1,6 @@
instance | minimal horizon | #solutions with minimal horizon
============================================================
problem-03-00.pddl | 10 | 12
problem-03-01.pddl | 11 | 40
problem-04-00.pddl | 14 | 180
problem-04-01.pddl | 13 | 120

View File

@@ -0,0 +1,42 @@
(define (domain Depot)
(:requirements :typing)
(:types place locatable - object
depot distributor - place
truck hoist surface - locatable
pallet crate - surface)
(:predicates (at ?x - locatable ?y - place)
(on ?x - crate ?y - surface)
(in ?x - crate ?y - truck)
(lifting ?x - hoist ?y - crate)
(available ?x - hoist)
(clear ?x - surface))
(:action Drive
:parameters (?x - truck ?y - place ?z - place)
:precondition (and (at ?x ?y))
:effect (and (not (at ?x ?y)) (at ?x ?z)))
(:action Lift
:parameters (?x - hoist ?y - crate ?z - surface ?p - place)
:precondition (and (at ?x ?p) (available ?x) (at ?y ?p) (on ?y ?z) (clear ?y))
:effect (and (not (at ?y ?p)) (lifting ?x ?y) (not (clear ?y)) (not (available ?x))
(clear ?z) (not (on ?y ?z))))
(:action Drop
:parameters (?x - hoist ?y - crate ?z - surface ?p - place)
:precondition (and (at ?x ?p) (at ?z ?p) (clear ?z) (lifting ?x ?y))
:effect (and (available ?x) (not (lifting ?x ?y)) (at ?y ?p) (not (clear ?z)) (clear ?y)
(on ?y ?z)))
(:action Load
:parameters (?x - hoist ?y - crate ?z - truck ?p - place)
:precondition (and (at ?x ?p) (at ?z ?p) (lifting ?x ?y))
:effect (and (not (lifting ?x ?y)) (in ?y ?z) (available ?x)))
(:action Unload
:parameters (?x - hoist ?y - crate ?z - truck ?p - place)
:precondition (and (at ?x ?p) (at ?z ?p) (available ?x) (in ?y ?z))
:effect (and (not (in ?y ?z)) (not (available ?x)) (lifting ?x ?y)))
)

View File

@@ -0,0 +1,34 @@
(define (problem depotprob1818) (:domain Depot)
(:objects
depot0 - Depot
distributor0 distributor1 - Distributor
truck0 truck1 - Truck
pallet0 pallet1 pallet2 - Pallet
crate0 crate1 - Crate
hoist0 hoist1 hoist2 - Hoist)
(:init
(at pallet0 depot0)
(clear crate1)
(at pallet1 distributor0)
(clear crate0)
(at pallet2 distributor1)
(clear pallet2)
(at truck0 distributor1)
(at truck1 depot0)
(at hoist0 depot0)
(available hoist0)
(at hoist1 distributor0)
(available hoist1)
(at hoist2 distributor1)
(available hoist2)
(at crate0 distributor0)
(on crate0 pallet1)
(at crate1 depot0)
(on crate1 pallet0)
)
(:goal (and
(on crate0 pallet2)
(on crate1 pallet1)
)
))

View File

@@ -0,0 +1,40 @@
(define (problem depotprob7512) (:domain Depot)
(:objects
depot0 - Depot
distributor0 distributor1 - Distributor
truck0 truck1 - Truck
pallet0 pallet1 pallet2 - Pallet
crate0 crate1 crate2 crate3 - Crate
hoist0 hoist1 hoist2 - Hoist)
(:init
(at pallet0 depot0)
(clear crate0)
(at pallet1 distributor0)
(clear crate3)
(at pallet2 distributor1)
(clear crate2)
(at truck0 depot0)
(at truck1 depot0)
(at hoist0 depot0)
(available hoist0)
(at hoist1 distributor0)
(available hoist1)
(at hoist2 distributor1)
(available hoist2)
(at crate0 depot0)
(on crate0 pallet0)
(at crate1 distributor1)
(on crate1 pallet2)
(at crate2 distributor1)
(on crate2 crate1)
(at crate3 distributor0)
(on crate3 pallet1)
)
(:goal (and
(on crate0 pallet2)
(on crate1 crate3)
(on crate2 pallet0)
(on crate3 pallet1)
)
))

View File

@@ -0,0 +1,4 @@
instance | minimal horizon | #solutions with minimal horizon
============================================================
problem-01.pddl | 10 | 16
problem-02.pddl | 15 | 448

View File

@@ -0,0 +1,79 @@
(define (domain driverlog)
(:requirements :typing)
(:types location locatable - object
driver truck obj - locatable
)
(:predicates
(at ?obj - locatable ?loc - location)
(in ?obj1 - obj ?obj - truck)
(driving ?d - driver ?v - truck)
(link ?x ?y - location) (path ?x ?y - location)
(empty ?v - truck)
)
(:action LOAD-TRUCK
:parameters
(?obj - obj
?truck - truck
?loc - location)
:precondition
(and (at ?truck ?loc) (at ?obj ?loc))
:effect
(and (not (at ?obj ?loc)) (in ?obj ?truck)))
(:action UNLOAD-TRUCK
:parameters
(?obj - obj
?truck - truck
?loc - location)
:precondition
(and (at ?truck ?loc) (in ?obj ?truck))
:effect
(and (not (in ?obj ?truck)) (at ?obj ?loc)))
(:action BOARD-TRUCK
:parameters
(?driver - driver
?truck - truck
?loc - location)
:precondition
(and (at ?truck ?loc) (at ?driver ?loc) (empty ?truck))
:effect
(and (not (at ?driver ?loc)) (driving ?driver ?truck) (not (empty ?truck))))
(:action DISEMBARK-TRUCK
:parameters
(?driver - driver
?truck - truck
?loc - location)
:precondition
(and (at ?truck ?loc) (driving ?driver ?truck))
:effect
(and (not (driving ?driver ?truck)) (at ?driver ?loc) (empty ?truck)))
(:action DRIVE-TRUCK
:parameters
(?truck - truck
?loc-from - location
?loc-to - location
?driver - driver)
:precondition
(and (at ?truck ?loc-from)
(driving ?driver ?truck) (link ?loc-from ?loc-to))
:effect
(and (not (at ?truck ?loc-from)) (at ?truck ?loc-to)))
(:action WALK
:parameters
(?driver - driver
?loc-from - location
?loc-to - location)
:precondition
(and (at ?driver ?loc-from) (path ?loc-from ?loc-to))
:effect
(and (not (at ?driver ?loc-from)) (at ?driver ?loc-to)))
)

View File

@@ -0,0 +1,48 @@
(define (problem DLOG-2-2-2)
(:domain driverlog)
(:objects
driver1 - driver
driver2 - driver
truck1 - truck
truck2 - truck
package1 - obj
package2 - obj
s0 - location
s1 - location
s2 - location
p1-0 - location
p1-2 - location
)
(:init
(at driver1 s2)
(at driver2 s2)
(at truck1 s0)
(empty truck1)
(at truck2 s0)
(empty truck2)
(at package1 s0)
(at package2 s0)
(path s1 p1-0)
(path p1-0 s1)
(path s0 p1-0)
(path p1-0 s0)
(path s1 p1-2)
(path p1-2 s1)
(path s2 p1-2)
(path p1-2 s2)
(link s0 s1)
(link s1 s0)
(link s0 s2)
(link s2 s0)
(link s2 s1)
(link s1 s2)
)
(:goal (and
(at driver1 s1)
(at truck1 s1)
(at package1 s0)
(at package2 s0)
))
)

View File

@@ -0,0 +1,59 @@
(define (problem DLOG-2-2-4)
(:domain driverlog)
(:objects
driver1 - driver
driver2 - driver
truck1 - truck
truck2 - truck
package1 - obj
package2 - obj
package3 - obj
package4 - obj
s0 - location
s1 - location
s2 - location
p0-1 - location
p2-0 - location
p2-1 - location
)
(:init
(at driver1 s1)
(at driver2 s0)
(at truck1 s1)
(empty truck1)
(at truck2 s2)
(empty truck2)
(at package1 s0)
(at package2 s0)
(at package3 s1)
(at package4 s1)
(path s0 p0-1)
(path p0-1 s0)
(path s1 p0-1)
(path p0-1 s1)
(path s2 p2-0)
(path p2-0 s2)
(path s0 p2-0)
(path p2-0 s0)
(path s2 p2-1)
(path p2-1 s2)
(path s1 p2-1)
(path p2-1 s1)
(link s1 s0)
(link s0 s1)
(link s1 s2)
(link s2 s1)
(link s2 s0)
(link s0 s2)
)
(:goal (and
(at driver2 s2)
(at truck1 s1)
(at truck2 s2)
(at package1 s1)
(at package2 s1)
(at package3 s2)
))
)

View File

@@ -0,0 +1,4 @@
instance | minimal horizon | #solutions with minimal horizon
============================================================
problem-01.pddl | 7 | 1
problem-03.pddl | 12 | 1056

View File

@@ -0,0 +1,75 @@
(define (domain satellite)
(:requirements :strips :equality :typing)
(:types satellite direction instrument mode)
(:predicates
(on_board ?i - instrument ?s - satellite)
(supports ?i - instrument ?m - mode)
(pointing ?s - satellite ?d - direction)
(power_avail ?s - satellite)
(power_on ?i - instrument)
(calibrated ?i - instrument)
(have_image ?d - direction ?m - mode)
(calibration_target ?i - instrument ?d - direction))
(:action turn_to
:parameters (?s - satellite ?d_new - direction ?d_prev - direction)
:precondition (and (pointing ?s ?d_prev)
)
:effect (and (pointing ?s ?d_new)
(not (pointing ?s ?d_prev))
)
)
(:action switch_on
:parameters (?i - instrument ?s - satellite)
:precondition (and (on_board ?i ?s)
(power_avail ?s)
)
:effect (and (power_on ?i)
(not (calibrated ?i))
(not (power_avail ?s))
)
)
(:action switch_off
:parameters (?i - instrument ?s - satellite)
:precondition (and (on_board ?i ?s)
(power_on ?i)
)
:effect (and (not (power_on ?i))
(power_avail ?s)
)
)
(:action calibrate
:parameters (?s - satellite ?i - instrument ?d - direction)
:precondition (and (on_board ?i ?s)
(calibration_target ?i ?d)
(pointing ?s ?d)
(power_on ?i)
)
:effect (calibrated ?i)
)
(:action take_image
:parameters (?s - satellite ?d - direction ?i - instrument ?m - mode)
:precondition (and (calibrated ?i)
(on_board ?i ?s)
(supports ?i ?m)
(power_on ?i)
(pointing ?s ?d)
(power_on ?i)
)
:effect (have_image ?d ?m)
)
)

View File

@@ -0,0 +1,30 @@
(define (problem strips-sat-x-1)
(:domain satellite)
(:objects
satellite0 - satellite
instrument0 - instrument
image1 - mode
spectrograph2 - mode
thermograph0 - mode
Star0 - direction
GroundStation1 - direction
GroundStation2 - direction
Phenomenon3 - direction
Phenomenon4 - direction
Star5 - direction
Phenomenon6 - direction
)
(:init
(supports instrument0 thermograph0)
(calibration_target instrument0 GroundStation2)
(on_board instrument0 satellite0)
(power_avail satellite0)
(pointing satellite0 Phenomenon6)
)
(:goal (and
(have_image Phenomenon4 thermograph0)
(have_image Star5 thermograph0)
(have_image Phenomenon6 thermograph0)
))
)

View File

@@ -0,0 +1,40 @@
(define (problem strips-sat-x-1)
(:domain satellite)
(:objects
satellite0 - satellite
instrument0 - instrument
instrument1 - instrument
infrared0 - mode
infrared1 - mode
image2 - mode
GroundStation1 - direction
Star0 - direction
GroundStation2 - direction
Planet3 - direction
Planet4 - direction
Phenomenon5 - direction
Phenomenon6 - direction
Star7 - direction
)
(:init
(supports instrument0 infrared1)
(supports instrument0 infrared0)
(calibration_target instrument0 Star0)
(supports instrument1 image2)
(supports instrument1 infrared1)
(supports instrument1 infrared0)
(calibration_target instrument1 GroundStation2)
(on_board instrument0 satellite0)
(on_board instrument1 satellite0)
(power_avail satellite0)
(pointing satellite0 Planet4)
)
(:goal (and
(have_image Planet3 infrared0)
(have_image Planet4 infrared0)
(have_image Phenomenon5 image2)
(have_image Phenomenon6 infrared0)
(have_image Star7 infrared0)
))
)

View File

@@ -0,0 +1,52 @@
(define (problem strips-sat-x-1)
(:domain satellite)
(:objects
satellite0 - satellite
instrument0 - instrument
instrument1 - instrument
instrument2 - instrument
satellite1 - satellite
instrument3 - instrument
image1 - mode
infrared0 - mode
spectrograph2 - mode
Star1 - direction
Star2 - direction
Star0 - direction
Star3 - direction
Star4 - direction
Phenomenon5 - direction
Phenomenon6 - direction
Phenomenon7 - direction
)
(:init
(supports instrument0 spectrograph2)
(supports instrument0 infrared0)
(calibration_target instrument0 Star1)
(supports instrument1 image1)
(calibration_target instrument1 Star2)
(supports instrument2 infrared0)
(supports instrument2 image1)
(calibration_target instrument2 Star0)
(on_board instrument0 satellite0)
(on_board instrument1 satellite0)
(on_board instrument2 satellite0)
(power_avail satellite0)
(pointing satellite0 Star4)
(supports instrument3 spectrograph2)
(supports instrument3 infrared0)
(supports instrument3 image1)
(calibration_target instrument3 Star0)
(on_board instrument3 satellite1)
(power_avail satellite1)
(pointing satellite1 Star0)
)
(:goal (and
(pointing satellite0 Phenomenon5)
(have_image Star3 infrared0)
(have_image Star4 spectrograph2)
(have_image Phenomenon5 spectrograph2)
(have_image Phenomenon7 spectrograph2)
))
)

View File

@@ -0,0 +1,5 @@
instance | minimal horizon | #solutions with minimal horizon
============================================================
problem-01.pddl | 9 | 12
problem-02.pddl | 13 | 240
problem-03.pddl | 11 | 276

View File

@@ -0,0 +1,65 @@
; IPC5 Domain: TPP Propositional
; Authors: Alfonso Gerevini and Alessandro Saetti
(define (domain TPP-Propositional)
(:requirements :strips :typing)
(:types place locatable level - object
depot market - place
truck goods - locatable)
(:predicates (loaded ?g - goods ?t - truck ?l - level)
(ready-to-load ?g - goods ?m - market ?l - level)
(stored ?g - goods ?l - level)
(on-sale ?g - goods ?m - market ?l - level)
(next ?l1 ?l2 - level)
(at ?t - truck ?p - place)
(connected ?p1 ?p2 - place))
(:action drive
:parameters (?t - truck ?from ?to - place)
:precondition (and (at ?t ?from) (connected ?from ?to))
:effect (and (not (at ?t ?from)) (at ?t ?to)))
; ### LOAD ###
; ?l1 is the level of ?g ready to be loaded at ?m before loading
; ?l2 is the level of ?g ready to be loaded at ?m after loading
; ?l3 is the level of ?g in ?t before loading
; ?l4 is the level of ?g in ?t after loading
(:action load
:parameters (?g - goods ?t - truck ?m - market ?l1 ?l2 ?l3 ?l4 - level)
:precondition (and (at ?t ?m) (loaded ?g ?t ?l3)
(ready-to-load ?g ?m ?l2) (next ?l2 ?l1) (next ?l4 ?l3))
:effect (and (loaded ?g ?t ?l4) (not (loaded ?g ?t ?l3))
(ready-to-load ?g ?m ?l1) (not (ready-to-load ?g ?m ?l2))))
; ### UNLOAD ###
; ?l1 is the level of ?g in ?t before unloading
; ?l2 is the level of ?g in ?t after unloading
; ?l3 is the level of ?g in ?d before unloading
; ?l4 is the level of ?g in ?d after unloading
(:action unload
:parameters (?g - goods ?t - truck ?d - depot ?l1 ?l2 ?l3 ?l4 - level)
:precondition (and (at ?t ?d) (loaded ?g ?t ?l2)
(stored ?g ?l3) (next ?l2 ?l1) (next ?l4 ?l3))
:effect (and (loaded ?g ?t ?l1) (not (loaded ?g ?t ?l2))
(stored ?g ?l4) (not (stored ?g ?l3))))
; ### BUY ###
; ?l1 is the level of ?g on sale at ?m before buying
; ?l2 is the level of ?g on sale at ?m after buying
; ?l3 is the level of ?g ready to be loaded at ?m before buying
; ?l4 is the level of ?g ready to be loaded at ?m after buying
(:action buy
:parameters (?t - truck ?g - goods ?m - market ?l1 ?l2 ?l3 ?l4 - level)
:precondition (and (at ?t ?m) (on-sale ?g ?m ?l2) (ready-to-load ?g ?m ?l3)
(next ?l2 ?l1) (next ?l4 ?l3))
:effect (and (on-sale ?g ?m ?l1) (not (on-sale ?g ?m ?l2))
(ready-to-load ?g ?m ?l4) (not (ready-to-load ?g ?m ?l3))))
)

View File

@@ -0,0 +1,28 @@
(define (problem TPP)
(:domain TPP-Propositional)
(:objects
goods1 goods2 - goods
truck1 - truck
market1 - market
depot1 - depot
level0 level1 - level)
(:init
(next level1 level0)
(ready-to-load goods1 market1 level0)
(ready-to-load goods2 market1 level0)
(stored goods1 level0)
(stored goods2 level0)
(loaded goods1 truck1 level0)
(loaded goods2 truck1 level0)
(connected depot1 market1)
(connected market1 depot1)
(on-sale goods1 market1 level1)
(on-sale goods2 market1 level1)
(at truck1 depot1))
(:goal (and
(stored goods1 level1)
(stored goods2 level1)))
)

View File

@@ -0,0 +1,33 @@
(define (problem TPP)
(:domain TPP-Propositional)
(:objects
goods1 goods2 goods3 - goods
truck1 - truck
market1 - market
depot1 - depot
level0 level1 - level)
(:init
(next level1 level0)
(ready-to-load goods1 market1 level0)
(ready-to-load goods2 market1 level0)
(ready-to-load goods3 market1 level0)
(stored goods1 level0)
(stored goods2 level0)
(stored goods3 level0)
(loaded goods1 truck1 level0)
(loaded goods2 truck1 level0)
(loaded goods3 truck1 level0)
(connected depot1 market1)
(connected market1 depot1)
(on-sale goods1 market1 level1)
(on-sale goods2 market1 level1)
(on-sale goods3 market1 level1)
(at truck1 depot1))
(:goal (and
(stored goods1 level1)
(stored goods2 level1)
(stored goods3 level1)))
)

View File

@@ -0,0 +1,38 @@
(define (problem TPP)
(:domain TPP-Propositional)
(:objects
goods1 goods2 goods3 goods4 - goods
truck1 - truck
market1 - market
depot1 - depot
level0 level1 - level)
(:init
(next level1 level0)
(ready-to-load goods1 market1 level0)
(ready-to-load goods2 market1 level0)
(ready-to-load goods3 market1 level0)
(ready-to-load goods4 market1 level0)
(stored goods1 level0)
(stored goods2 level0)
(stored goods3 level0)
(stored goods4 level0)
(loaded goods1 truck1 level0)
(loaded goods2 truck1 level0)
(loaded goods3 truck1 level0)
(loaded goods4 truck1 level0)
(connected depot1 market1)
(connected market1 depot1)
(on-sale goods1 market1 level1)
(on-sale goods2 market1 level1)
(on-sale goods3 market1 level1)
(on-sale goods4 market1 level1)
(at truck1 depot1))
(:goal (and
(stored goods1 level1)
(stored goods2 level1)
(stored goods3 level1)
(stored goods4 level1)))
)

View File

@@ -0,0 +1,5 @@
instance | minimal horizon | #solutions with minimal horizon
============================================================
problem-02.pddl | 8 | 12
problem-03.pddl | 11 | 540
problem-04.pddl | 14 | 60480

View File

@@ -5,10 +5,7 @@
#include <plasp/pddl/Context.h>
#include <plasp/pddl/Domain.h>
#include <plasp/pddl/ExpressionContext.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/pddl/expressions/Type.h>
#include <plasp/utils/IO.h>
#include <plasp/utils/ParserException.h>
namespace plasp
{
@@ -23,31 +20,33 @@ namespace pddl
void Action::parseDeclaration(Context &context, Domain &domain)
{
auto &parser = context.parser;
auto action = std::make_unique<Action>(Action());
action->m_name = context.parser.parseIdentifier(isIdentifier);
action->m_name = parser.parseIdentifier();
context.parser.expect<std::string>(":parameters");
context.parser.expect<std::string>("(");
parser.expect<std::string>(":parameters");
parser.expect<std::string>("(");
ExpressionContext expressionContext(domain, action->m_parameters);
// Read parameters
expressions::Variable::parseTypedDeclarations(context, expressionContext);
context.parser.expect<std::string>(")");
parser.expect<std::string>(")");
// Parse preconditions and effects
while (context.parser.currentCharacter() != ')')
while (!parser.testAndReturn(')'))
{
context.parser.expect<std::string>(":");
parser.expect<std::string>(":");
if (context.parser.probeIdentifier("precondition", isIdentifier))
if (parser.testIdentifierAndSkip("precondition"))
action->m_precondition = parsePreconditionExpression(context, expressionContext);
else if (context.parser.probeIdentifier("effect", isIdentifier))
else if (parser.testIdentifierAndSkip("effect"))
action->m_effect = parseEffectExpression(context, expressionContext);
context.parser.skipWhiteSpace();
parser.skipWhiteSpace();
}
// Store new action
@@ -88,5 +87,13 @@ const Expression *Action::effect() const
////////////////////////////////////////////////////////////////////////////////////////////////////
void Action::normalizeParameterNames()
{
for (size_t i = 0; i < m_parameters.size(); i++)
m_parameters[i]->setName("X" + std::to_string(i));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@@ -44,7 +44,7 @@ Description Description::fromStream(std::istream &istream)
{
Description description;
description.m_context.parser.readStream("std::cin", istream);
description.m_context.parser.read("std::cin", istream);
description.parse();
return description;
@@ -56,7 +56,7 @@ Description Description::fromFile(const std::string &path)
{
Description description;
description.m_context.parser.readFile(path);
description.m_context.parser.read(path);
description.parse();
return description;
@@ -73,7 +73,7 @@ Description Description::fromFiles(const std::vector<std::string> &paths)
std::for_each(paths.cbegin(), paths.cend(),
[&](const auto &path)
{
description.m_context.parser.readFile(path);
description.m_context.parser.read(path);
});
description.parse();
@@ -126,7 +126,6 @@ void Description::parse()
{
auto &parser = m_context.parser;
parser.setCaseSensitive(false);
parser.removeComments(";", "\n", false);
// First, determine the locations of domain and problem
@@ -155,7 +154,7 @@ void Description::findSections()
parser.skipWhiteSpace();
while (!parser.atEndOfStream())
while (!parser.atEnd())
{
const auto position = parser.position();
@@ -163,20 +162,20 @@ void Description::findSections()
parser.expect<std::string>("define");
parser.expect<std::string>("(");
if (parser.probe<std::string>("domain"))
if (parser.testAndSkip<std::string>("domain"))
{
if (m_domainPosition != -1)
throw utils::ParserException(parser, "PDDL description may not contain two domains");
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.probe<std::string>("problem"))
else if (m_context.parser.testAndSkip<std::string>("problem"))
{
if (m_problemPosition != -1)
throw utils::ParserException(parser, "PDDL description may currently not contain two problems");
throw utils::ParserException(parser.coordinate(), "PDDL description may currently not contain two problems");
m_problem = std::make_unique<Problem>(Problem(m_context, *m_domain));
@@ -188,7 +187,7 @@ void Description::findSections()
else
{
const auto sectionIdentifier = parser.parse<std::string>();
throw utils::ParserException(parser, "unknown PDDL section “" + sectionIdentifier + "");
throw utils::ParserException(parser.coordinate(), "unknown PDDL section “" + sectionIdentifier + "");
}
m_context.parser.skipWhiteSpace();
@@ -205,5 +204,12 @@ void Description::checkConsistency()
////////////////////////////////////////////////////////////////////////////////////////////////////
void Description::normalizeParameterNames()
{
m_domain->normalizeParameterNames();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@@ -3,13 +3,11 @@
#include <algorithm>
#include <plasp/pddl/ConsistencyException.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/pddl/IO.h>
#include <plasp/pddl/expressions/Constant.h>
#include <plasp/pddl/expressions/PredicateDeclaration.h>
#include <plasp/pddl/expressions/PrimitiveType.h>
#include <plasp/pddl/expressions/Variable.h>
#include <plasp/utils/IO.h>
#include <plasp/utils/ParserException.h>
namespace plasp
@@ -43,7 +41,7 @@ void Domain::findSections()
parser.expect<std::string>("(");
parser.expect<std::string>("domain");
m_name = m_context.parser.parseIdentifier(isIdentifier);
m_name = m_context.parser.parseIdentifier();
parser.expect<std::string>(")");
@@ -53,7 +51,7 @@ void Domain::findSections()
if (unique && sectionPosition != -1)
{
parser.seek(value);
throw utils::ParserException(parser, "only one “:" + sectionName + "” section allowed");
throw utils::ParserException(parser.coordinate(), "only one “:" + sectionName + "” section allowed");
}
sectionPosition = value;
@@ -72,38 +70,38 @@ void Domain::findSections()
const auto sectionIdentifierPosition = parser.position();
// Save the parser position of the individual sections for later parsing
if (parser.probeIdentifier("requirements", isIdentifier))
if (parser.testIdentifierAndSkip("requirements"))
setSectionPosition("requirements", m_requirementsPosition, position, true);
else if (parser.probeIdentifier("types", isIdentifier))
else if (parser.testIdentifierAndSkip("types"))
setSectionPosition("types", m_typesPosition, position, true);
else if (parser.probeIdentifier("constants", isIdentifier))
else if (parser.testIdentifierAndSkip("constants"))
setSectionPosition("constants", m_constantsPosition, position, true);
else if (parser.probeIdentifier("predicates", isIdentifier))
else if (parser.testIdentifierAndSkip("predicates"))
setSectionPosition("predicates", m_predicatesPosition, position, true);
else if (parser.probeIdentifier("action", isIdentifier))
else if (parser.testIdentifierAndSkip("action"))
{
m_actionPositions.emplace_back(-1);
setSectionPosition("action", m_actionPositions.back(), position);
}
else if (parser.probeIdentifier("functions", isIdentifier)
|| parser.probeIdentifier("constraints", isIdentifier)
|| parser.probeIdentifier("durative-action", isIdentifier)
|| parser.probeIdentifier("derived", isIdentifier))
else if (parser.testIdentifierAndSkip("functions")
|| parser.testIdentifierAndSkip("constraints")
|| parser.testIdentifierAndSkip("durative-action")
|| parser.testIdentifierAndSkip("derived"))
{
parser.seek(sectionIdentifierPosition);
const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
const auto sectionIdentifier = parser.parseIdentifier();
m_context.logger.logWarning(parser, "section type “" + sectionIdentifier + "” currently unsupported");
m_context.logger.logWarning(parser.coordinate(), "section type “" + sectionIdentifier + "” currently unsupported");
parser.seek(sectionIdentifierPosition);
}
else
{
const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
const auto sectionIdentifier = parser.parseIdentifier();
parser.seek(position);
throw utils::ParserException(m_context.parser, "unknown domain section “" + sectionIdentifier + "");
throw utils::ParserException(parser.coordinate(), "unknown domain section “" + sectionIdentifier + "");
}
// Skip section for now and parse it later
@@ -274,12 +272,14 @@ bool Domain::hasRequirement(Requirement::Type requirementType) const
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::checkRequirement(Requirement::Type requirementType) const
void Domain::checkRequirement(Requirement::Type requirementType)
{
if (hasRequirement(requirementType))
return;
throw ConsistencyException("requirement “" + Requirement(requirementType).toPDDL() + "” used but never declared");
m_context.logger.logWarning(m_context.parser.coordinate(), "requirement “" + Requirement(requirementType).toPDDL() + "” used but never declared");
m_requirements.push_back(requirementType);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -340,7 +340,7 @@ void Domain::parseTypeSection()
while (parser.currentCharacter() != ')')
{
if (parser.currentCharacter() == '(')
throw utils::ParserException(parser, "only primitive types are allowed in type section");
throw utils::ParserException(parser.coordinate(), "only primitive types are allowed in type section");
expressions::PrimitiveType::parseTypedDeclaration(m_context, *this);
@@ -415,5 +415,22 @@ void Domain::checkConsistency()
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::normalizeParameterNames()
{
std::for_each(m_predicates.begin(), m_predicates.end(),
[](auto &predicate)
{
predicate->normalizeParameterNames();
});
std::for_each(m_actions.begin(), m_actions.end(),
[](auto &action)
{
action->normalizeParameterNames();
});
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@@ -3,7 +3,6 @@
#include <plasp/pddl/Context.h>
#include <plasp/pddl/Domain.h>
#include <plasp/pddl/ExpressionContext.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/pddl/IO.h>
#include <plasp/pddl/expressions/And.h>
#include <plasp/pddl/expressions/Imply.h>
@@ -12,7 +11,6 @@
#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
@@ -49,12 +47,12 @@ ExpressionPointer parsePreconditionExpression(Context &context,
const auto expressionIdentifierPosition = parser.position();
if (parser.probeIdentifier("forall", isIdentifier)
|| parser.probeIdentifier("preference", isIdentifier))
if (parser.testIdentifierAndSkip("forall")
|| parser.testIdentifierAndSkip("preference"))
{
// TODO: refactor
parser.seek(expressionIdentifierPosition);
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
const auto expressionIdentifier = parser.parseIdentifier();
parser.seek(position);
return expressions::Unsupported::parse(context);
@@ -89,32 +87,32 @@ ExpressionPointer parseExpression(Context &context, ExpressionContext &expressio
const auto expressionIdentifierPosition = parser.position();
if (parser.probeIdentifier("exists", isIdentifier)
|| parser.probeIdentifier("forall", isIdentifier)
|| parser.probeIdentifier("-", isIdentifier)
|| parser.probeIdentifier("=", isIdentifier)
|| parser.probeIdentifier("*", isIdentifier)
|| parser.probeIdentifier("+", isIdentifier)
|| parser.probeIdentifier("-", isIdentifier)
|| parser.probeIdentifier("/", isIdentifier)
|| parser.probeIdentifier(">", isIdentifier)
|| parser.probeIdentifier("<", isIdentifier)
|| parser.probeIdentifier("=", isIdentifier)
|| parser.probeIdentifier(">=", isIdentifier)
|| parser.probeIdentifier("<=", isIdentifier))
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(isIdentifier);
const auto expressionIdentifier = parser.parseIdentifier();
parser.seek(position);
return expressions::Unsupported::parse(context);
}
parser.seek(expressionIdentifierPosition);
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
const auto expressionIdentifier = parser.parseIdentifier();
parser.seek(position);
throw utils::ParserException(context.parser, "expression type “" + expressionIdentifier + "” unknown or not allowed in this context");
throw utils::ParserException(parser.coordinate(), "expression type “" + expressionIdentifier + "” unknown or not allowed in this context");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -134,11 +132,11 @@ ExpressionPointer parseEffectExpression(Context &context, ExpressionContext &exp
const auto expressionIdentifierPosition = parser.position();
if (parser.probeIdentifier("forall", isIdentifier)
|| parser.probeIdentifier("when", isIdentifier))
if (parser.testIdentifierAndSkip("forall")
|| parser.testIdentifierAndSkip("when"))
{
parser.seek(expressionIdentifierPosition);
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
const auto expressionIdentifier = parser.parseIdentifier();
parser.seek(position);
return expressions::Unsupported::parse(context);
@@ -168,37 +166,39 @@ ExpressionPointer parseEffectBodyExpression(Context &context, ExpressionContext
const auto expressionIdentifierPosition = parser.position();
if (parser.probeIdentifier("=", isIdentifier)
|| parser.probeIdentifier("assign", isIdentifier)
|| parser.probeIdentifier("scale-up", isIdentifier)
|| parser.probeIdentifier("scale-down", isIdentifier)
|| parser.probeIdentifier("increase", isIdentifier)
|| parser.probeIdentifier("decrease", isIdentifier))
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(isIdentifier);
const auto expressionIdentifier = parser.parseIdentifier();
parser.seek(position);
return expressions::Unsupported::parse(context);
}
parser.seek(expressionIdentifierPosition);
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
const auto expressionIdentifier = parser.parseIdentifier();
parser.seek(position);
throw utils::ParserException(context.parser, "expression type “" + expressionIdentifier + "” unknown or not allowed in this context");
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(context.parser, "expected predicate");
throw utils::ParserException(parser.coordinate(), "expected predicate");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -229,15 +229,15 @@ ExpressionPointer parseAtomicFormula(Context &context, ExpressionContext &expres
const auto position = parser.position();
if (!parser.probe<std::string>("("))
if (!parser.testAndSkip<std::string>("("))
return nullptr;
const auto expressionIdentifierPosition = parser.position();
if (parser.probeIdentifier("=", isIdentifier))
if (parser.testIdentifierAndSkip("="))
{
parser.seek(expressionIdentifierPosition);
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
const auto expressionIdentifier = parser.parseIdentifier();
parser.seek(position);
return expressions::Unsupported::parse(context);

View File

@@ -2,7 +2,6 @@
#include <plasp/pddl/Context.h>
#include <plasp/pddl/ExpressionContext.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/pddl/IO.h>
#include <plasp/pddl/Problem.h>
#include <plasp/pddl/expressions/At.h>
@@ -46,20 +45,20 @@ std::unique_ptr<InitialState> InitialState::parseDeclaration(Context &context,
const auto expressionIdentifierPosition = parser.position();
if (parser.probeIdentifier("=", isIdentifier))
if (parser.testIdentifierAndSkip("="))
{
parser.seek(expressionIdentifierPosition);
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
const auto expressionIdentifier = parser.parseIdentifier();
parser.seek(position);
return expressions::Unsupported::parse(context);
}
parser.seek(expressionIdentifierPosition);
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
const auto expressionIdentifier = parser.parseIdentifier();
parser.seek(position);
throw utils::ParserException(parser, "expression type “" + expressionIdentifier + "” unknown or not allowed in this context");
throw utils::ParserException(parser.coordinate(), "expression type “" + expressionIdentifier + "” unknown or not allowed in this context");
};
parser.skipWhiteSpace();

View File

@@ -4,10 +4,8 @@
#include <plasp/pddl/Domain.h>
#include <plasp/pddl/ExpressionContext.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/pddl/IO.h>
#include <plasp/pddl/expressions/Constant.h>
#include <plasp/utils/IO.h>
#include <plasp/utils/ParserException.h>
namespace plasp
@@ -43,7 +41,7 @@ void Problem::findSections()
parser.expect<std::string>("(");
parser.expect<std::string>("problem");
m_name = parser.parseIdentifier(isIdentifier);
m_name = parser.parseIdentifier();
parser.expect<std::string>(")");
@@ -53,7 +51,7 @@ void Problem::findSections()
if (unique && sectionPosition != -1)
{
parser.seek(value);
throw utils::ParserException(parser, "only one “:" + sectionName + "” section allowed");
throw utils::ParserException(parser.coordinate(), "only one “:" + sectionName + "” section allowed");
}
sectionPosition = value;
@@ -71,34 +69,34 @@ void Problem::findSections()
const auto sectionIdentifierPosition = parser.position();
// TODO: check order of the sections
if (parser.probeIdentifier("domain", isIdentifier))
if (parser.testIdentifierAndSkip("domain"))
setSectionPosition("domain", m_domainPosition, position, true);
else if (parser.probeIdentifier("requirements", isIdentifier))
else if (parser.testIdentifierAndSkip("requirements"))
setSectionPosition("requirements", m_requirementsPosition, position, true);
else if (parser.probeIdentifier("objects", isIdentifier))
else if (parser.testIdentifierAndSkip("objects"))
setSectionPosition("objects", m_objectsPosition, position, true);
else if (parser.probeIdentifier("init", isIdentifier))
else if (parser.testIdentifierAndSkip("init"))
setSectionPosition("init", m_initialStatePosition, position, true);
else if (parser.probeIdentifier("goal", isIdentifier))
else if (parser.testIdentifierAndSkip("goal"))
setSectionPosition("goal", m_goalPosition, position, true);
else if (parser.probeIdentifier("constraints", isIdentifier)
|| parser.probeIdentifier("metric", isIdentifier)
|| parser.probeIdentifier("length", isIdentifier))
else if (parser.testIdentifierAndSkip("constraints")
|| parser.testIdentifierAndSkip("metric")
|| parser.testIdentifierAndSkip("length"))
{
parser.seek(sectionIdentifierPosition);
const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
const auto sectionIdentifier = parser.parseIdentifier();
m_context.logger.logWarning(parser, "section type “" + sectionIdentifier + "” currently unsupported");
m_context.logger.logWarning(parser.coordinate(), "section type “" + sectionIdentifier + "” currently unsupported");
parser.seek(sectionIdentifierPosition);
}
else
{
const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
const auto sectionIdentifier = parser.parseIdentifier();
parser.seek(position);
throw utils::ParserException(m_context.parser, "unknown problem section “" + sectionIdentifier + "");
throw utils::ParserException(parser.coordinate(), "unknown problem section “" + sectionIdentifier + "");
}
// Skip section for now and parse it later
@@ -201,10 +199,10 @@ void Problem::parseDomainSection()
parser.skipWhiteSpace();
const auto domainName = parser.parseIdentifier(isIdentifier);
const auto domainName = parser.parseIdentifier();
if (m_domain.name() != domainName)
throw utils::ParserException(parser, "domains do not match (“" + m_domain.name() + "” and “" + domainName + "”)");
throw utils::ParserException(parser.coordinate(), "domains do not match (“" + m_domain.name() + "” and “" + domainName + "”)");
parser.expect<std::string>(")");
}
@@ -256,12 +254,14 @@ bool Problem::hasRequirement(Requirement::Type requirementType) const
////////////////////////////////////////////////////////////////////////////////////////////////////
void Problem::checkRequirement(Requirement::Type requirementType) const
void Problem::checkRequirement(Requirement::Type requirementType)
{
if (hasRequirement(requirementType))
return;
throw ConsistencyException("requirement “" + Requirement(requirementType).toPDDL() + "” used but never declared");
m_context.logger.logWarning(m_context.parser.coordinate(), "requirement “" + Requirement(requirementType).toPDDL() + "” used but never declared");
m_requirements.push_back(requirementType);
}
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -4,8 +4,6 @@
#include <boost/assign.hpp>
#include <boost/bimap.hpp>
#include <plasp/pddl/Identifier.h>
#include <plasp/utils/IO.h>
#include <plasp/utils/ParserException.h>
namespace plasp
@@ -84,17 +82,19 @@ Requirement::Requirement(Requirement::Type type)
Requirement Requirement::parse(Context &context)
{
const auto requirementName = context.parser.parseIdentifier(isIdentifier);
auto &parser = context.parser;
const auto requirementName = parser.parseIdentifier();
const auto match = requirementTypesToPDDL.right.find(requirementName);
if (match == requirementTypesToPDDL.right.end())
throw utils::ParserException(context.parser, "unknown PDDL requirement “" + requirementName + "");
throw utils::ParserException(parser.coordinate(), "unknown PDDL requirement “" + requirementName + "");
const auto requirementType = match->second;
if (requirementType == Requirement::Type::GoalUtilities)
context.logger.logWarning(context.parser, "requirement “goal-utilities” is not part of the PDDL 3.1 specification");
context.logger.logWarning(parser.coordinate(), "requirement “goal-utilities” is not part of the PDDL 3.1 specification");
return Requirement(match->second);
}

View File

@@ -6,7 +6,6 @@
#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
@@ -20,10 +19,11 @@ namespace pddl
//
////////////////////////////////////////////////////////////////////////////////////////////////////
TranslatorASP::TranslatorASP(const Description &description, utils::LogStream &outputStream)
TranslatorASP::TranslatorASP(Description &description, utils::LogStream &outputStream)
: m_description(description),
m_outputStream(outputStream)
{
m_description.normalizeParameterNames();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -85,62 +85,99 @@ void TranslatorASP::translateTypes() const
if (types.empty())
{
m_outputStream << utils::Keyword("type") << "(object)." << std::endl;
m_outputStream
<< utils::RuleName("type") << "("
<< utils::Keyword("type") << "(" << utils::String("object") << "))." << std::endl;
return;
}
std::for_each(types.cbegin(), types.cend(),
[&](const auto &type)
{
const auto typeName = utils::escapeASP(type->name());
m_outputStream << utils::Keyword("type") << "(" << typeName << ")." << std::endl;
m_outputStream
<< utils::RuleName("type") << "("
<< utils::Keyword("type") << "("
<< utils::String(type->name())
<< "))." << 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::RuleName("inherits") << "(" << utils::Keyword("type")
<< "(" << utils::String(type->name()) << "), " << utils::Keyword("type")
<< "(" << utils::String(parentType->name()) << "))." << std::endl;
});
});
m_outputStream
<< utils::Keyword("inherits") << "(" << utils::Keyword("type")
<< "(" << typeName << "), " << utils::Keyword("type")
<< "(" << parentTypeName << "))." << std::endl
<< utils::Keyword("hasType") << "(" << utils::Variable("X") << ", "
<< utils::Keyword("type") << "(" << parentTypeName << ")) :- "
<< utils::Keyword("hasType") << "(" << utils::Variable("X") << ", "
<< utils::Keyword("type") << "(" << typeName << "))." << std::endl;
});
});
<< std::endl
<< utils::RuleName("has") << "("
<< utils::Variable("X") << ", "
<< utils::Keyword("type") << "(" << utils::Variable("T2") << ")) :- "
<< utils::RuleName("has") << "("
<< utils::Variable("X") << ", "
<< utils::Keyword("type") << "(" << utils::Variable("T1") << ")), "
<< utils::RuleName("inherits") << "("
<< utils::Keyword("type") << "(" << utils::Variable("T1") << "), "
<< utils::Keyword("type") << "(" << utils::Variable("T2") << "))."
<< std::endl;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void TranslatorASP::translatePredicates() const
{
m_outputStream << utils::Heading2("predicates");
m_outputStream << utils::Heading2("variables");
const auto &predicates = m_description.domain().predicates();
const auto printPredicateName =
[&](const auto &predicate)
{
if (predicate->arguments().empty())
{
m_outputStream << utils::String(predicate->name());
return;
}
m_outputStream << "(" << utils::String(predicate->name());
this->translateVariablesHead(predicate->arguments());
m_outputStream << ")";
};
std::for_each(predicates.cbegin(), predicates.cend(),
[&](const auto &predicate)
{
m_outputStream << std::endl;
m_outputStream
<< std::endl
<< utils::RuleName("variable") << "("
<< utils::Keyword("variable") << "(";
m_outputStream << utils::Keyword("predicate") << "(" << utils::escapeASP(predicate->name());
printPredicateName(predicate);
this->translateVariablesHead(predicate->arguments());
m_outputStream << ")";
m_outputStream << "))";
this->translateVariablesBody(predicate->arguments());
m_outputStream << ".";
});
m_outputStream << std::endl;
m_outputStream
<< std::endl << std::endl
<< utils::RuleName("boolean") << "(" << utils::Boolean("true") << ")." << std::endl
<< utils::RuleName("boolean") << "(" << utils::Boolean("false") << ")." << std::endl
<< std::endl
<< utils::RuleName("contains") << "("
<< utils::Keyword("variable") << "(" << utils::Variable("X") << "), "
<< utils::Keyword("value") << "(" << utils::Variable("X") << ", " << utils::Variable("B") << ")) :- "
<< utils::RuleName("variable") << "(" << utils::Keyword("variable") << "(" << utils::Variable("X") << ")), "
<< utils::RuleName("boolean") << "(" << utils::Variable("B") << ")."
<< std::endl;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -154,38 +191,52 @@ void TranslatorASP::translateActions() const
const auto printActionName =
[&](const auto &action)
{
m_outputStream << utils::Keyword("action") << "(" << utils::escapeASP(action.name());
m_outputStream << utils::Keyword("action") << "(";
if (action.parameters().empty())
{
m_outputStream << utils::String(action.name()) << ")";
return;
}
m_outputStream << "(" << utils::String(action.name());
this->translateVariablesHead(action.parameters());
m_outputStream << ")";
m_outputStream << "))";
};
std::for_each(actions.cbegin(), actions.cend(),
[&](const auto &action)
{
// TODO: rename
const auto translateLiteral =
[&](const auto &ruleHead, const auto &literal)
[&](const auto &ruleHead, const auto &literal, bool enumerateEffects = false)
{
m_outputStream << std::endl << utils::Keyword(ruleHead) << "(";
m_outputStream << std::endl << utils::RuleName(ruleHead) << "(";
printActionName(*action);
// TODO: implement conditional effects
if (enumerateEffects)
m_outputStream << ", " << utils::Keyword("effect") << "(" << utils::Reserved("unconditional") << ")";
m_outputStream << ", ";
this->translateLiteral(literal);
m_outputStream << ") :- ";
m_outputStream << ") :- " << utils::RuleName("action") << "(";
printActionName(*action);
m_outputStream << ".";
m_outputStream << ").";
};
m_outputStream << std::endl;
// Name
m_outputStream << utils::RuleName("action") << "(";
printActionName(*action);
m_outputStream << ")";
this->translateVariablesBody(action->parameters());
@@ -225,7 +276,7 @@ void TranslatorASP::translateActions() const
if (effect.expressionType() == Expression::Type::Predicate
|| effect.expressionType() == Expression::Type::Not)
{
translateLiteral("postcondition", effect);
translateLiteral("postcondition", effect, true);
}
// Assuming a conjunction
else
@@ -238,7 +289,7 @@ void TranslatorASP::translateActions() const
std::for_each(andExpression.arguments().cbegin(), andExpression.arguments().cend(),
[&](const auto *argument)
{
translateLiteral("postcondition", *argument);
translateLiteral("postcondition", *argument, true);
});
}
}
@@ -256,24 +307,25 @@ void TranslatorASP::translateConstants(const std::string &heading, const express
std::for_each(constants.cbegin(), constants.cend(),
[&](const auto &constant)
{
const auto constantName = utils::escapeASP(constant->name());
m_outputStream << std::endl << utils::Keyword("constant")
<< "(" << constantName << ")." << std::endl;
m_outputStream << std::endl
<< utils::RuleName("constant") << "("
<< utils::Keyword("constant") << "("
<< utils::String(constant->name())
<< "))." << std::endl;
const auto *type = constant->type();
if (type != nullptr)
{
m_outputStream << utils::Keyword("hasType") << "("
<< utils::Keyword("constant") << "(" << constantName << "), "
<< utils::Keyword("type") << "(" << utils::escapeASP(type->name()) << "))." << std::endl;
m_outputStream << utils::RuleName("has") << "("
<< utils::Keyword("constant") << "(" << utils::String(constant->name()) << "), "
<< utils::Keyword("type") << "(" << utils::String(type->name()) << "))." << std::endl;
}
else
{
m_outputStream << utils::Keyword("hasType") << "("
<< utils::Keyword("constant") << "(" << constantName << "), "
<< utils::Keyword("type") << "(object))." << std::endl;
m_outputStream << utils::RuleName("has") << "("
<< utils::Keyword("constant") << "(" << utils::String(constant->name()) << "), "
<< utils::Keyword("type") << "(" << utils::String("object") << "))." << std::endl;
}
});
}
@@ -285,19 +337,12 @@ void TranslatorASP::translateVariablesHead(const expressions::Variables &variabl
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 << ", " << utils::Variable(variable.name());
}
m_outputStream << ")";
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -323,15 +368,15 @@ void TranslatorASP::translateVariablesBody(const expressions::Variables &variabl
const auto &type = *dynamic_cast<const expressions::PrimitiveType *>(variable.type());
m_outputStream << utils::Keyword("hasType") << "("
<< utils::Variable(utils::escapeASPVariable(variable.name())) << ", "
<< utils::Keyword("type") << "(" << utils::escapeASP(type.name()) << "))";
m_outputStream << utils::RuleName("has") << "("
<< utils::Variable(variable.name()) << ", "
<< utils::Keyword("type") << "(" << utils::String(type.name()) << "))";
}
else
{
m_outputStream << utils::Keyword("hasType") << "("
<< utils::Variable(utils::escapeASPVariable(variable.name())) << ", "
<< utils::Keyword("type") << "(object))";
m_outputStream << utils::RuleName("has") << "("
<< utils::Variable(variable.name()) << ", "
<< utils::Keyword("type") << "(" << utils::String("object") << "))";
}
}
}
@@ -343,17 +388,29 @@ void TranslatorASP::translateLiteral(const Expression &literal) const
// Translate single predicate
if (literal.expressionType() == Expression::Type::Predicate)
{
this->translatePredicate(dynamic_cast<const expressions::Predicate &>(literal));
m_outputStream << ", " << utils::Keyword("true");
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::Boolean("true") << ")";
}
// Assuming that "not" expression may only contain a predicate
else if (literal.expressionType() == Expression::Type::Not)
{
const auto &notExpression = dynamic_cast<const expressions::Not &>(literal);
if (notExpression.argument()->expressionType() != Expression::Type::Predicate)
throw utils::TranslatorException("only negations of primitive predicates supported as literals currently");
const auto &predicate = dynamic_cast<const expressions::Predicate &>(*notExpression.argument());
m_outputStream << utils::Keyword("variable") << "(";
this->translatePredicate(predicate);
m_outputStream << ", " << utils::Keyword("false");
m_outputStream << "), " << utils::Keyword("value") << "(";
this->translatePredicate(predicate);
m_outputStream << ", " << utils::Boolean("false") << ")";
}
else
throw utils::TranslatorException("only primitive predicates and their negations supported as literals currently");
@@ -363,40 +420,38 @@ void TranslatorASP::translateLiteral(const Expression &literal) const
void TranslatorASP::translatePredicate(const expressions::Predicate &predicate) const
{
m_outputStream << utils::Keyword("predicate") << "(" << utils::escapeASP(predicate.name());
const auto &arguments = predicate.arguments();
if (arguments.empty())
{
m_outputStream << ")";
m_outputStream << utils::String(predicate.name());
return;
}
m_outputStream << "(";
m_outputStream << "(" << utils::String(predicate.name());
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()) << ")";
m_outputStream << utils::Keyword("constant") << "(" << utils::String(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()));
m_outputStream << utils::Variable(variable.name());
}
else
throw utils::TranslatorException("only variables and constants supported in predicates currently");
}
m_outputStream << "))";
m_outputStream << ")";
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -438,11 +493,19 @@ void TranslatorASP::translateInitialState() const
std::for_each(initialStateFacts.cbegin(), initialStateFacts.cend(),
[&](const auto &fact)
{
m_outputStream << std::endl << utils::Keyword("initialState") << "(";
m_outputStream << std::endl << utils::RuleName("initialState") << "(";
// Translate single predicate
if (fact->expressionType() == Expression::Type::Predicate)
this->translatePredicate(dynamic_cast<const expressions::Predicate &>(*fact));
{
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::Boolean("true") << ")";
}
// Assuming that "not" expression may only contain a predicate
else if (fact->expressionType() == Expression::Type::Not)
{
@@ -457,7 +520,17 @@ void TranslatorASP::translateInitialState() const
m_outputStream << ").";
});
m_outputStream << std::endl;
m_outputStream
<< std::endl << std::endl
<< utils::RuleName("initialState") << "("
<< utils::Keyword("variable") << "(" << utils::Variable("X") << "), "
<< utils::Keyword("value") << "(" << utils::Variable("X") << ", " << utils::Boolean("false") << ")) :- "
<< utils::RuleName("variable") << "(" << utils::Keyword("variable") << "(" << utils::Variable("X") << ")), "
<< utils::Keyword("not") << " "
<< utils::RuleName("initialState") << "("
<< utils::Keyword("variable") << "(" << utils::Variable("X") << "), "
<< utils::Keyword("value") << "(" << utils::Variable("X") << ", " << utils::Boolean("true") << "))."
<< std::endl;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -473,7 +546,7 @@ void TranslatorASP::translateGoal() const
if (goal.expressionType() == Expression::Type::Predicate
|| goal.expressionType() == Expression::Type::Not)
{
m_outputStream << std::endl << utils::Keyword("goal") << "(";
m_outputStream << std::endl << utils::RuleName("goal") << "(";
translateLiteral(goal);
@@ -486,7 +559,7 @@ void TranslatorASP::translateGoal() const
std::for_each(andExpression.arguments().cbegin(), andExpression.arguments().cend(),
[&](const auto *argument)
{
m_outputStream << std::endl << utils::Keyword("goal") << "(";
m_outputStream << std::endl << utils::RuleName("goal") << "(";
this->translateLiteral(*argument);

View File

@@ -37,7 +37,7 @@ ConstantPointer Constant::parseDeclaration(Context &context)
auto constant = std::make_unique<Constant>(Constant());
constant->m_name = context.parser.parseIdentifier(isIdentifier);
constant->m_name = context.parser.parseIdentifier();
BOOST_ASSERT(constant->m_name != "-");
@@ -71,7 +71,7 @@ void Constant::parseTypedDeclaration(Context &context, Domain &domain, Constants
context.parser.skipWhiteSpace();
// Check for typing information
if (!context.parser.probe('-'))
if (!context.parser.testAndSkip<char>('-'))
return;
// If existing, parse and store parent type
@@ -113,7 +113,7 @@ void Constant::parseTypedDeclarations(Context &context, Domain &domain)
domain.checkRequirement(Requirement::Type::Typing);
// If no types are given, check that typing is not a requirement
else if (domain.hasRequirement(Requirement::Type::Typing))
throw utils::ParserException(parser, "constant has undeclared type");
throw utils::ParserException(parser.coordinate(), "constant has undeclared type");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -140,32 +140,36 @@ void Constant::parseTypedDeclarations(Context &context, Problem &problem)
problem.checkRequirement(Requirement::Type::Typing);
// If no types are given, check that typing is not a requirement
else if (problem.hasRequirement(Requirement::Type::Typing))
throw utils::ParserException(context.parser, "constant has undeclared type");
throw utils::ParserException(parser.coordinate(), "constant has undeclared type");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
Constant *Constant::parseAndFind(Context &context, const Domain &domain)
{
context.parser.skipWhiteSpace();
auto &parser = context.parser;
const auto constantName = context.parser.parseIdentifier(isIdentifier);
parser.skipWhiteSpace();
const auto constantName = parser.parseIdentifier();
auto *constant = parseAndFind(constantName, domain.constants());
if (constant != nullptr)
return constant;
throw utils::ParserException(context.parser, "constant “" + constantName + "” used but never declared");
throw utils::ParserException(parser.coordinate(), "constant “" + constantName + "” used but never declared");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
Constant *Constant::parseAndFind(Context &context, const Problem &problem)
{
context.parser.skipWhiteSpace();
auto &parser = context.parser;
const auto constantName = context.parser.parseIdentifier(isIdentifier);
parser.skipWhiteSpace();
const auto constantName = parser.parseIdentifier();
auto *constant = parseAndFind(constantName, problem.domain().constants());
@@ -177,7 +181,7 @@ Constant *Constant::parseAndFind(Context &context, const Problem &problem)
if (constant)
return constant;
throw utils::ParserException(context.parser, "constant “" + constantName + "” used but never declared");
throw utils::ParserException(parser.coordinate(), "constant “" + constantName + "” used but never declared");
}
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -13,6 +13,7 @@ namespace expressions
//
////////////////////////////////////////////////////////////////////////////////////////////////////
// TODO: make static character string literal
const std::string Imply::Identifier = "imply";
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -3,7 +3,6 @@
#include <plasp/pddl/Context.h>
#include <plasp/pddl/Domain.h>
#include <plasp/pddl/ExpressionContext.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/pddl/Problem.h>
#include <plasp/pddl/expressions/Constant.h>
#include <plasp/pddl/expressions/Variable.h>
@@ -34,13 +33,13 @@ PredicatePointer Predicate::parse(Context &context, ExpressionContext &expressio
const auto position = parser.position();
if (!parser.probe<std::string>("("))
if (!parser.testAndSkip<std::string>("("))
{
parser.seek(position);
return nullptr;
}
const auto predicateName = parser.parseIdentifier(isIdentifier);
const auto predicateName = parser.parseIdentifier();
const auto &predicates = expressionContext.domain.predicates();
const auto matchingPredicate = std::find_if(predicates.cbegin(), predicates.cend(),
@@ -97,13 +96,13 @@ PredicatePointer Predicate::parse(Context &context, const Problem &problem)
const auto position = parser.position();
if (!parser.probe<std::string>("("))
if (!parser.testAndSkip<std::string>("("))
{
parser.seek(position);
return nullptr;
}
const auto predicateName = parser.parseIdentifier(isIdentifier);
const auto predicateName = parser.parseIdentifier();
const auto &predicates = problem.domain().predicates();
const auto matchingPredicate = std::find_if(predicates.cbegin(), predicates.cend(),
@@ -122,12 +121,12 @@ PredicatePointer Predicate::parse(Context &context, const Problem &problem)
predicate->m_name = predicateName;
context.parser.skipWhiteSpace();
parser.skipWhiteSpace();
while (context.parser.currentCharacter() != ')')
while (parser.currentCharacter() != ')')
{
if (context.parser.currentCharacter() == '?')
throw utils::ParserException(context.parser, "variables not allowed in this context");
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);

View File

@@ -3,7 +3,6 @@
#include <plasp/pddl/Context.h>
#include <plasp/pddl/Domain.h>
#include <plasp/pddl/ExpressionContext.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/pddl/expressions/Constant.h>
#include <plasp/pddl/expressions/Variable.h>
@@ -33,7 +32,7 @@ void PredicateDeclaration::parse(Context &context, Domain &domain)
auto predicate = std::make_unique<PredicateDeclaration>(PredicateDeclaration());
predicate->m_name = context.parser.parseIdentifier(isIdentifier);
predicate->m_name = context.parser.parseIdentifier();
// Flag predicate as correctly declared in the types section
predicate->setDeclared();
@@ -80,6 +79,14 @@ const Variables &PredicateDeclaration::arguments() const
////////////////////////////////////////////////////////////////////////////////////////////////////
void PredicateDeclaration::normalizeParameterNames()
{
for (size_t i = 0; i < m_parameters.size(); i++)
m_parameters[i]->setName("X" + std::to_string(i));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
}

View File

@@ -43,7 +43,7 @@ void PrimitiveType::parseDeclaration(Context &context, Domain &domain)
context.parser.skipWhiteSpace();
const auto typeName = context.parser.parseIdentifier(isIdentifier);
const auto typeName = context.parser.parseIdentifier();
const auto match = std::find_if(types.cbegin(), types.cend(),
[&](const auto &primitiveType)
@@ -76,7 +76,7 @@ void PrimitiveType::parseTypedDeclaration(Context &context, Domain &domain)
context.parser.skipWhiteSpace();
// Check for type inheritance
if (!context.parser.probe('-'))
if (!context.parser.testAndSkip<char>('-'))
return;
domain.checkRequirement(Requirement::Type::Typing);
@@ -102,14 +102,16 @@ void PrimitiveType::parseTypedDeclaration(Context &context, Domain &domain)
PrimitiveType *PrimitiveType::parseAndFind(Context &context, Domain &domain)
{
auto &parser = context.parser;
auto &types = domain.types();
context.parser.skipWhiteSpace();
parser.skipWhiteSpace();
const auto typeName = context.parser.parseIdentifier(isIdentifier);
const auto typeName = parser.parseIdentifier();
if (typeName.empty())
throw utils::ParserException(context.parser, "no type supplied");
throw utils::ParserException(parser.coordinate(), "no type supplied");
const auto match = std::find_if(types.cbegin(), types.cend(),
[&](const auto &primitiveType)
@@ -122,11 +124,11 @@ PrimitiveType *PrimitiveType::parseAndFind(Context &context, Domain &domain)
// Only "object" is allowed as an implicit type
if (typeName == "object" || typeName == "objects")
{
context.logger.logWarning(context.parser, "primitive type “" + typeName + "” should be declared");
context.logger.logWarning(parser.coordinate(), "primitive type “" + typeName + "” should be declared");
types.emplace_back(std::make_unique<expressions::PrimitiveType>(typeName));
}
else
throw utils::ParserException(context.parser, "type “" + typeName + "” used but never declared");
throw utils::ParserException(parser.coordinate(), "type “" + typeName + "” used but never declared");
return types.back().get();
}

View File

@@ -1,6 +1,5 @@
#include <plasp/pddl/expressions/Unsupported.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/pddl/IO.h>
namespace plasp
@@ -24,9 +23,9 @@ UnsupportedPointer Unsupported::parse(Context &context)
parser.expect<std::string>("(");
expression->m_type = parser.parseIdentifier(isIdentifier);
expression->m_type = parser.parseIdentifier();
context.logger.logWarning(context.parser, "expression type “" + expression->m_type + "” currently unsupported in this context");
context.logger.logWarning(parser.coordinate(), "expression type “" + expression->m_type + "” currently unsupported in this context");
skipSection(parser);

View File

@@ -7,7 +7,6 @@
#include <plasp/pddl/Context.h>
#include <plasp/pddl/Domain.h>
#include <plasp/pddl/ExpressionContext.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/pddl/expressions/Either.h>
#include <plasp/pddl/expressions/PrimitiveType.h>
#include <plasp/pddl/expressions/Type.h>
@@ -36,13 +35,15 @@ Variable::Variable()
void Variable::parseDeclaration(Context &context, Variables &parameters)
{
context.parser.skipWhiteSpace();
auto &parser = context.parser;
context.parser.expect<std::string>("?");
parser.skipWhiteSpace();
parser.expect<std::string>("?");
auto variable = std::make_unique<Variable>(Variable());
variable->m_name = context.parser.parseIdentifier(isIdentifier);
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(),
@@ -52,7 +53,7 @@ void Variable::parseDeclaration(Context &context, Variables &parameters)
});
if (match != parameters.cend())
throw utils::ParserException(context.parser, "variable “" + variable->m_name + "” already declared in this scope");
throw utils::ParserException(parser.coordinate(), "variable “" + variable->m_name + "” already declared in this scope");
// Flag variable for potentially upcoming type declaration
variable->setDirty();
@@ -75,7 +76,7 @@ void Variable::parseTypedDeclaration(Context &context, ExpressionContext &expres
parser.skipWhiteSpace();
// Check if the variable has a type declaration
if (!parser.probe('-'))
if (!parser.testAndSkip<char>('-'))
return;
const auto setType =
@@ -132,18 +133,20 @@ void Variable::parseTypedDeclarations(Context &context, ExpressionContext &expre
expressionContext.checkRequirement(Requirement::Type::Typing);
// If no types are given, check that typing is not a requirement
else if (expressionContext.hasRequirement(Requirement::Type::Typing))
throw utils::ParserException(parser, "variable has undeclared type");
throw utils::ParserException(parser.coordinate(), "variable has undeclared type");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
const Variable *Variable::parseAndFind(Context &context, const ExpressionContext &expressionContext)
{
context.parser.skipWhiteSpace();
auto &parser = context.parser;
context.parser.expect<std::string>("?");
parser.skipWhiteSpace();
const auto variableName = context.parser.parseIdentifier(isIdentifier);
parser.expect<std::string>("?");
const auto variableName = parser.parseIdentifier();
const auto &variables = expressionContext.parameters;
@@ -154,13 +157,20 @@ const Variable *Variable::parseAndFind(Context &context, const ExpressionContext
});
if (match == variables.cend())
throw utils::ParserException(context.parser, "parameter “" + variableName + "” used but never declared");
throw utils::ParserException(parser.coordinate(), "parameter “" + variableName + "” used but never declared");
return match->get();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Variable::setName(std::string name)
{
m_name = name;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
const std::string &Variable::name() const
{
return m_name;

View File

@@ -31,7 +31,7 @@ AssignedVariable::AssignedVariable(const Variable &variable, const Value &value)
////////////////////////////////////////////////////////////////////////////////////////////////////
AssignedVariable AssignedVariable::fromSAS(utils::Parser &parser, const Variables &variables)
AssignedVariable AssignedVariable::fromSAS(utils::Parser<> &parser, const Variables &variables)
{
AssignedVariable assignedVariable;
@@ -43,7 +43,7 @@ AssignedVariable AssignedVariable::fromSAS(utils::Parser &parser, const Variable
////////////////////////////////////////////////////////////////////////////////////////////////////
AssignedVariable AssignedVariable::fromSAS(utils::Parser &parser, const Variable &variable)
AssignedVariable AssignedVariable::fromSAS(utils::Parser<> &parser, const Variable &variable)
{
AssignedVariable assignedVariable;

View File

@@ -23,7 +23,7 @@ AxiomRule::AxiomRule(AxiomRule::Conditions conditions, AxiomRule::Condition post
////////////////////////////////////////////////////////////////////////////////////////////////////
AxiomRule AxiomRule::fromSAS(utils::Parser &parser, const Variables &variables)
AxiomRule AxiomRule::fromSAS(utils::Parser<> &parser, const Variables &variables)
{
parser.expect<std::string>("begin_rule");

Some files were not shown because too many files have changed in this diff Show More