Zoelver


Adapting a prolog implementation to be used as a classical planner

Published on October 23, 2026 by Zoey Drassinower

classical planning projects

2 min READ

Github Repo: https://github.com/drass02/zoelver

zoelver

A Classical Planner Implementation by Roberto Drassinower and Zoey Drassinower

The Zoelver project is the result of hobby investigation into the field of classical planning. Our goal was to understand the current popular planning algorithms, and implement them in Rust. We aimed to implement a planner which could solve a set of homework problems assigned in the CISC352 course at Queen’s University. Special thanks goes out to Prof. Christian Muise for his guidance throughout this project.

Zoelver consists of 3 major parts:

  • the command-line interface
  • the query engine
  • the planning engine (aka solver)

Command Line Interface

Build at execute the rust project to enter the CLI.

The comnand “input " executes the commands in the specified file, or script.txt if no file is specified. See the included script.txt for an example, or check out main.rs to see the full list of commands and their usage.

Query Engine

The query engine is a prolog-like logic engine, which we use to determine which actions are takeable, apply effects of actions, and determine whether the goal state has been reached.

The query engine operates on a single datatype, which we call a “function”. A function is akin to a “term” in prolog, where it refers to a single horn clause (either a fact or a rule). Again, like prolog, the query engine maintains a set of rules (which we call inferences) and facts. The argument of a fact may be a literal or a variable (which call entities). Unlike prolog, we require that a variable have a finite domain of values, explicitly specified in the factbase config.
Once the fact base is loaded, it may be queried. The query engine will find any suitable bindings to free variables in the query so that the query is True, otherwise it will return False. If the query is an inference (or action) it finds a set of variable bindings to make all preconditions in the inference (or action) True.

The use of a query engine was based on leveraging Roberto’s experience as a programmer working with prolog, rather than any performance-related motivations. However, by starting with the conventions of logic programming, rather than immediately adopting the standards of automated planning, we gained insight into the design standards of PDDL and experienced first-hand the motivations behind modern planning methods.

Solver

The solver implements a number of popular planning strategies:

  • Naive breadth first search
  • Iterative Width (non-serialized, so only compatible with single-fact goals)
    • IW is currently only supported up to width 2
  • Lazy best-first heuristic search with h^add, h^max
  • (todo) Best-first width-based search (todo) Optionally, IW can be run before any of the complete algorithms

Instructive Readings and Resources

The following resources were instrumental in developing our understanding of classical planning beyond simple naive search, and are highly recommended.

Novelty and Iterated Width: https://www.ijcai.org/proceedings/2021/0702.pdf How to compute Forward Heuristics (hAdd, hMax): https://cw.fel.cvut.cz/old/_media/courses/a4m36pah/07_relaxation.pdf