PDDL with the Feasbl SDK
Once you know what a planning model looks like, the SDK is the easiest way to build one from application data. This page shows how Feasbl fits into that workflow.
The Feasbl SDK makes it easier to build planning problems without writing the PDDL files by hand.
That matters when the problem is coming from your application data. Instead of serialising a file first, you can construct the same planning model from code, using the values your product already has.
What that looks like
At a high level, you build:
- the domain rules
- the objects in the problem
- the initial state
- the goal state
The SDK then turns that into the planning input Feasbl expects. That keeps the planning model close to the rest of your application logic.
Example
More SDK languages
We are adding more SDK languages.
- JavaScript
- Python
import * as feasbl from '@feasbl/sdk';
const plan = feasbl.planning('delivery');
const location = plan.type('location');
const packageItem = plan.type('package');
const truckAt = plan.predicate('truck-at', [location]);
const packageAt = plan.predicate('package-at', [packageItem, location]);
const packageLoaded = plan.predicate('package-loaded', [packageItem]);
const connected = plan.predicate('connected', [location, location]);
plan.action('load-package', action => {
const item = action.param('item', packageItem);
const loc = action.param('loc', location);
return {
preconditions: plan.and(
truckAt(loc),
packageAt(item, loc),
),
effects: plan.and(
packageLoaded(item),
plan.not(packageAt(item, loc)),
),
};
});
plan.action('move-truck', action => {
const from = action.param('from', location);
const to = action.param('to', location);
return {
preconditions: plan.and(
connected(from, to),
truckAt(from),
),
effects: plan.and(
plan.not(truckAt(from)),
truckAt(to),
),
};
});
plan.action('unload-package', action => {
const item = action.param('item', packageItem);
const loc = action.param('loc', location);
return {
preconditions: plan.and(
truckAt(loc),
packageLoaded(item),
),
effects: plan.and(
packageAt(item, loc),
plan.not(packageLoaded(item)),
),
};
});
const depotA = plan.object('A', location);
const depotB = plan.object('B', location);
const box = plan.object('box', packageItem);
plan.initially(
connected(depotA, depotB),
connected(depotB, depotA),
truckAt(depotA),
packageAt(box, depotA),
);
plan.goal(packageAt(box, depotB));
const files = plan.toFiles();
console.log(files['domain.pddl']);
console.log(files['problem.pddl']);
# Python support is not shown here yet.
# The SDK shape in JavaScript is: define types, predicates, actions, objects,
# initial facts, and a goal, then render domain.pddl and problem.pddl.
Why use the SDK
- it avoids hand-writing PDDL for every run
- it fits dynamic problems that come from live product data
- it keeps the model generation inside your codebase
- it makes it easier to reuse the same planning pattern across different cases