Skip to main content

Loki: PDDL Parsing and Translation in C++ and Python

Loki is a C++20 library with Python bindings for parsing and translation of PDDL files. Loki separates the parsing and translation of domain and problem files, allowing users to effectively work with collection of problems.

The parser is based on the canonical parser structure proposed in the Boost Spirit X3 library.

The translator is based on the method presented in section four of the paper "Concise finite-domain representations for PDDL planning tasks by Malte Helmert (AIJ 2009)".

Supported PDDL Requirements

  • :strips
  • :typing
  • :negative-preconditions
  • :disjunctive-preconditions
  • :equality
  • :existential-preconditions
  • :universal-preconditions
  • :quantified-preconditions
  • :conditional-effects
  • :numeric-fluents
  • :adl
  • :derived-predicates
  • :action-costs
  • :non-deterministic (unsupported in the translator)
  • :probabilistic-effects (unsupported in the translator)

Dependencies

Loki depends on a fraction of Boost's header-only libraries (Fusion, Spirit x3, Container), its performance benchmarking framework depends on GoogleBenchmark, and its testing framework depends on GoogleTest.

Loki consumes native dependencies from Python packages:

  • pyyggdrasil >= 0.0.20, < 0.1 for shared third-party native dependencies.

The shared workspace layout, layered install order, and the common build-from-source and CMake-integration patterns are documented in the Planning and Learning build instructions; the sections below cover loki/pypddl-specific details.

For offline/local development, install pyyggdrasil from the sibling source checkout instead:

cd ../yggdrasil
uv pip install --python ../loki/.venv/bin/python .

Build C++

Install Loki's native dependency providers into the active Python environment, then configure CMake with their native prefixes:

python -m pip install 'pyyggdrasil>=0.0.20,<0.1'

cmake -S . -B build

CMake discovers the installed pyyggdrasil automatically through cmake/bootstrap_pyyggdrasil.cmake (which locates the package and adds its native prefix to CMAKE_PREFIX_PATH, after which find_package(yggdrasil) provides the shared helper functions) and links against the yggdrasil::yggdrasil target. To point at a different prefix explicitly:

cmake -S . -B build \
  -DCMAKE_PREFIX_PATH="$(python -m pyyggdrasil --prefix)"

cmake --build build -j4

CMake options:

Option Default Description
LOKI_BUILD_TESTS OFF Build Loki tests.
LOKI_BUILD_EXECUTABLES OFF Build Loki executables.
LOKI_BUILD_PROFILING OFF Build Loki profiling targets.
LOKI_BUILD_PYPDDL OFF Build Loki for the pypddl Python wheel.

Run tests from a build configured with -DLOKI_BUILD_TESTS=ON:

ctest --test-dir build --output-on-failure

Install Loki from a configured build directory with:

cmake --install build --prefix=<path/to/installation-directory>

Build Python

python -m pip install .

Python API

The Python package exposes the semantic parser, translator, and reparseable PDDL formatter through pypddl.formalism:

from pypddl import formalism as pddl

parser = pddl.Parser("""
(define (domain ready-domain)
  (:predicates (ready))
)
""")

translation = pddl.translate_domain(parser.domain())
domain_text = pddl.format_domain(translation.translated_domain)
reparsed = pddl.Parser(domain_text)
assert reparsed.domain().get_name() == "ready-domain"

With default options the parser completes :action-costs artifacts and the translator compiles typing and materializes equality; see Parser and Translator Options to override.

C++ API

The umbrella header exposes the semantic parser, translator, and reparseable PDDL formatter through the top-level loki namespace:

#include <loki/loki.hpp>

#include <string>

int main()
{
    auto parser = loki::Parser(std::string { "(define (domain ready-domain) (:predicates (ready)))" });
    const auto translation = loki::translate_domain(parser.get_domain());
    const auto domain_text = loki::format_domain(translation.get_translated_domain());
    auto reparsed = loki::Parser(domain_text);
    return reparsed.get_domain().get_name() == "ready-domain" ? 0 : 1;
}

Parser and Translator Options

Both APIs accept options at construction/translation time. The library defaults are normalization-friendly for downstream consumers; every option can be turned off individually.

ParserOptions (second argument of Parser):

Option Default Description
strict false Strict semantic validation for requirements, arity, and type compatibility. Numeric-fluents violations error even in permissive mode: reads require :fluents/:numeric-fluents/:action-costs, and writes other than (increase (total-cost) ...) require :fluents/:numeric-fluents.
add_action_costs true Complete missing :action-costs artifacts (total-cost function, initial value, minimize metric) instead of erroring. If the domain declares neither :action-costs nor :fluents/:numeric-fluents, additionally injects the requirement and a unit-cost effect (increase (total-cost) 1) into every action that does not already write total-cost. Genuine numeric domains are left untouched: an absent metric means unit costs.

TranslatorOptions (second argument of translate_domain/translate_task):

Option Default Description
compile_typing true Compile typing away into type predicates and remove type annotations.
compile_conditional_effects false Multiply conditional effects out into unconditional actions; the normalization phases re-run afterwards so preconditions stay conjunctive (quantified when-conditions become derived predicates). Worst case exponential in the number of conditional effects per action.
materialize_equality true Add the = predicate and (= o o) initial literals. Turn off for consumers with native equality handling.

Pass the same TranslatorOptions to the domain and the task translation; mismatched options between the two can fail (e.g. equality materialization requires the = predicate added during domain translation).

options = pddl.TranslatorOptions()
options.materialize_equality = False
translation = pddl.translate_domain(parser.domain(), options)

The loki executable exposes the same options as opt-in flags (all off by default): --strict, --add-action-costs, --compile-typing, --compile-conditional-effects, and --materialize-equality.

CMake Integration

This section covers pypddl-specific paths and targets; the general pattern for consuming the native prefixes from CMake is in the common CMake integration instructions.

The Python package pypddl installs Loki's native headers, shared library, and CMake package config under pypddl.native_prefix(). It depends on pyyggdrasil>=0.0.20,<0.1 for third-party native dependencies:

import pypddl
import pyyggdrasil

print(pypddl.cmake_prefix())       # prefix to put on CMAKE_PREFIX_PATH
print(pypddl.cmake_dir())          # directory containing lokiConfig.cmake
print(pyyggdrasil.cmake_prefix())

The same paths are available from the shell via python -m pypddl --prefix, --cmake-dir, --include-dir, and --version.

Downstream CMake projects should include the native prefixes of pypddl and its native package dependencies in CMAKE_PREFIX_PATH:

cmake -S . -B build \
  -DCMAKE_PREFIX_PATH="$(python -m pypddl --prefix);$(python -m pyyggdrasil --prefix)"

Loki exports the loki::parsers target.

Running the Executables

The executable illustrates how to use Loki. It is disabled by default and can be enabled with -DLOKI_BUILD_EXECUTABLES=ON. Example PDDL inputs are available from the benchmark submodule:

git submodule update --init --recursive data/planning-benchmarks
./build/exe/loki \
  data/planning-benchmarks/tests/classical/gripper/domain.pddl \
  data/planning-benchmarks/tests/classical/gripper/test-1.pddl

Use --out-domain/--out-problem to write the translated PDDL to files, and see ./build/exe/loki --help for the parser and translator flags (--strict, --add-action-costs, --compile-typing, --compile-conditional-effects, --materialize-equality).

Citing Loki

If you use Loki in your research, please cite it as follows:

@misc{drexler-zenodo2026,
  author =       "Dominik Drexler",
  title =        "{Loki}: A {PDDL} Parser and Normalizer",
  publisher =    "Zenodo",
  year =         "2026",
  doi =          "10.5281/zenodo.20081136",
  url =          "https://doi.org/10.5281/zenodo.20081136",
}

Acknowledgements

This work was partially supported by the Wallenberg AI, Autonomous Systems and Software Program (WASP) funded by the Knut and Alice Wallenberg Foundation.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pypddl-1.0.18.tar.gz (3.8 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pypddl-1.0.18-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

pypddl-1.0.18-cp313-cp313-macosx_11_0_arm64.whl (914.7 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

pypddl-1.0.18-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

pypddl-1.0.18-cp312-cp312-macosx_11_0_arm64.whl (914.7 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

pypddl-1.0.18-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

pypddl-1.0.18-cp311-cp311-macosx_11_0_arm64.whl (890.0 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

pypddl-1.0.18-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

pypddl-1.0.18-cp310-cp310-macosx_11_0_arm64.whl (914.7 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

pypddl-1.0.18-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

pypddl-1.0.18-cp39-cp39-macosx_11_0_arm64.whl (890.0 kB view details)

Uploaded CPython 3.9macOS 11.0+ ARM64

File details

Details for the file pypddl-1.0.18.tar.gz.

File metadata

  • Download URL: pypddl-1.0.18.tar.gz
  • Upload date:
  • Size: 3.8 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pypddl-1.0.18.tar.gz
Algorithm Hash digest
SHA256 a071e4a1ba7f67942bf010b05749f3f0a27e3ac587ba386eee7022fde264d56d
MD5 e5e23487d554e8087414062e4b262eb2
BLAKE2b-256 289ce13e5b29d36f6093f4866d7a981bd87c42b4c36a3bad626c279bd88cebfe

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypddl-1.0.18.tar.gz:

Publisher: release.yml on planning-and-learning/loki

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypddl-1.0.18-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pypddl-1.0.18-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 9ef9ebb7a2eb7b46745684bda39f6859781b3dca5ab3c7337df78f47de9042ab
MD5 7dd0ff7c8c0714054b8537122977b82d
BLAKE2b-256 0ad6b2d3af69e04289c81dc4dd196f50cbce477ffc7a4025a76200813d2ec2fc

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypddl-1.0.18-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on planning-and-learning/loki

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypddl-1.0.18-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pypddl-1.0.18-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ebc1f3948e70707e181f30549a02f54a526634281e1e34e0975c91daf8a529ac
MD5 fcdd82d7253a8a5f4f187a07263e1adc
BLAKE2b-256 dfe283ae41c991dbc898dee6825a4e30655651020c7f469def32fcf87ed795cf

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypddl-1.0.18-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: release.yml on planning-and-learning/loki

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypddl-1.0.18-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pypddl-1.0.18-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 f81c57a468bd584aba3165c2e6823b04da74f6c5f9e1be580292778cec565546
MD5 61dc9e226f786390e430f084f529bc55
BLAKE2b-256 8a0da462b48160aff38b395aad2bad3e20f444d7f14a16c518b2713605ed5047

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypddl-1.0.18-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on planning-and-learning/loki

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypddl-1.0.18-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pypddl-1.0.18-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1c98233f50d58cffcb3a9d230fbd74b4b7b13f7c6143672db2af7a0750229549
MD5 c713b67a20f24488f0da2d9353f59a30
BLAKE2b-256 98a9a6952d0dde888baba1a4e8926c4fe53e39da052781c50ab8f63dca31d65b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypddl-1.0.18-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: release.yml on planning-and-learning/loki

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypddl-1.0.18-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pypddl-1.0.18-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 b5367c78fec525b5b6166fc610d62fe522b5c48e5aba06ba8b785700eb7df90d
MD5 e461992844cd2f31c8e4194d2e5af527
BLAKE2b-256 86e27b983da847ebfbab370dba837b3b2808d235b86c1577c85cb3e49793fc88

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypddl-1.0.18-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on planning-and-learning/loki

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypddl-1.0.18-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pypddl-1.0.18-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f9e53d3353b8f5a4aba58f59fd9f3370c195239754ba43403665e30df31b81be
MD5 bb92b1d2ebc03e39c1a70cdb8278051b
BLAKE2b-256 7056ae8346fef7c23704d7ae741f9b1f0362365c16431bc5dd3ceb52b7cad7e1

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypddl-1.0.18-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: release.yml on planning-and-learning/loki

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypddl-1.0.18-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pypddl-1.0.18-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 46f8af0446f6b984fb68f4a054477c613cd47cc42cdb57799e04254b14322855
MD5 6dbf8cf984146b4044de728850dbb2de
BLAKE2b-256 d482c10927198d8c2c2e0ab2cad198bf5189de8a91c13181669cda705cd33267

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypddl-1.0.18-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on planning-and-learning/loki

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypddl-1.0.18-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pypddl-1.0.18-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6ff304c63bcee9d90d64a054e19957926f8e20718979c396ac0def88b0cf440f
MD5 bb4a21c852ff2005c7e0465ba67b33e0
BLAKE2b-256 a79dbba7e243b1bae10ea3b2035887ea1a342be2c6cb25ea6b4454abfffe9928

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypddl-1.0.18-cp310-cp310-macosx_11_0_arm64.whl:

Publisher: release.yml on planning-and-learning/loki

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypddl-1.0.18-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pypddl-1.0.18-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 fb886887f4cceeb0168d29712abcc1016010bf14fa35e95fac28a3b0882550c7
MD5 000aa73d62b2723c2a88ed8abbb7cdfe
BLAKE2b-256 203fcf748c54f1f23124847a3bf9a5ec3048a8b061b90083f13aab63920f08ce

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypddl-1.0.18-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on planning-and-learning/loki

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypddl-1.0.18-cp39-cp39-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pypddl-1.0.18-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9557aaa7afbda326304f3d10e41fd8932d4c0d0a35d1ed71aba7019ce7313ed1
MD5 b00125336729e3c4a1e4d196bb2e067d
BLAKE2b-256 4891aadf7ef73f8d49758fc9fa52e211344da1c93c21522034d8884181d9b78f

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypddl-1.0.18-cp39-cp39-macosx_11_0_arm64.whl:

Publisher: release.yml on planning-and-learning/loki

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page