Data Types¶
L2P serves as an intermediary between Large Language Models (LLMs) and the construction of reliable planning components in PDDL. All data structures are modeled as Pydantic BaseModel subclasses with strict validation. These are the core data structures that flow through every L2P pipeline - generation, validation, formatting, and planning.
Each model class carries a tag class variable (XML tag tuple) used by the LLM
output parser to identify which XML block maps to which model.
Tip
See L2P for the full autogenerated API reference of every model field, validator, and method. Below we provide a high-level overview with concrete JSON ↔ Python examples.
You can find more information on PDDL here.
LogicalCondition¶
LogicalCondition is a type alias - Union[str, Dict[str, Any]] - that represents
a single node in a PDDL formula. Nearly every condition/effect model uses it.
1. Simple Predicates & Numeric Checks (str)::
"(at ?r ?l)"
"(>= (battery-level ?r) 20)"
2. Logical Operators (Dict)::
# NOT
{"operator": "not", "condition": "(busy ?r)"}
# AND / OR
{
"operator": "and", # or "or"
"conditions": ["(has-power ?r)", {"operator": "not", "condition": "(busy ?r)"}]
}
# IMPLY
{
"operator": "imply",
"antecedent": ["(at ?r ?l)"],
"consequent": ["(can-transmit ?r)"]
}
3. Quantifiers (Dict)::
# FORALL / EXISTS
{
"quantifier": "forall", # or "exists"
"parameters": [{"variable": "?p", "type": "packet"}],
"conditions": ["(transmitted ?p)"]
}
4. PDDL 3.0 Trajectory Constraints (Dict)::
# ALWAYS / SOMETIME / AT-MOST-ONCE
{"operator": "always", "condition": "(has-power ?r)"}
# WITHIN / HOLD-AFTER (time-bounded)
{"operator": "within", "time": 10.5, "condition": "(transmitted ?p)"}
# HOLD-DURING (interval)
{"operator": "hold-during", "time_start": 5.0, "time_end": 15.0, "condition": "(transmitting ?r)"}
# SOMETIME-AFTER / SOMETIME-BEFORE (relational)
{"operator": "sometime-after", "antecedent": "(transmitted ?p)", "consequent": "(acknowledged ?p)"}
# ALWAYS-WITHIN (time-bounded relational)
{"operator": "always-within", "time": 5.0, "antecedent": "(error-detected ?r)", "consequent": "(safe-mode ?r)"}
5. PDDL 3.0 Preferences (Dict)::
{
"preference": "pref_transmit_early",
"condition": {"operator": "sometime", "condition": "(transmitted ?p)"}
}
Domain Models¶
Requirement¶
A single PDDL requirement flag.
{"name": ":typing", "desc": "Enables typed variables"}
Fields: name (str, must start with :), desc (Optional[str])
PDDLType¶
A PDDL type, optionally with a parent type for inheritance.
{"name": "rover", "parent": "object", "desc": "A planetary rover"}
{"name": "waypoint", "parent": "object", "desc": "A navigable location"}
Fields: name (str), parent (str), desc (Optional[str])
A flat dict {name: desc} is still accepted as input to the LLM prompt,
but the canonical form is the structured JSON above.
Constant¶
A named object that is available in every problem instance of a domain.
{"name": "base_station", "type": "location", "desc": "The main hub"}
Fields: name (str), type (str), desc (Optional[str])
Parameter¶
A typed parameter variable used in actions, predicates, and functions.
{"variable": "?r", "type": "rover", "desc": "A rover"}
Fields: variable (str, must start with ?), type (str), desc (Optional[str])
Predicate¶
A predicate symbol with typed parameters.
{
"name": "at",
"params": [
{"variable": "?r", "type": "rover"},
{"variable": "?l", "type": "location"}
],
"desc": "True if rover is at location"
}
Fields: name (str), params (List[Parameter]), desc (Optional[str])
Function¶
A numeric fluent (PDDL 2.1+) with typed parameters.
{
"name": "battery-level",
"params": [{"variable": "?r", "type": "rover"}],
"desc": "Current battery level of the rover"
}
Fields: name (str), params (List[Parameter]), desc (Optional[str])
DerivedPredicate¶
A derived predicate / axiom (PDDL 2.1+) - defined in terms of a condition rather than an action effect.
{
"name": "can-move",
"params": [{"variable": "?r", "type": "rover"}],
"condition": "(> (battery-level ?r) 0.0)",
"desc": "Derived from having positive battery"
}
Fields: name (str), params (List[Parameter]), condition (LogicalCondition), desc (Optional[str])
ActionPrecondition¶
The precondition of an action, consisting of a list of logical conditions.
{
"conditions": [
"(at ?r ?from)",
{"operator": "not", "condition": "(busy ?r)"}
],
"desc": "Rover must be at start and not busy"
}
Fields: conditions (List[LogicalCondition]), desc (Optional[str])
ActionEffect¶
The effect of an action, split into additive, deletive, numeric, and conditional blocks.
{
"add": ["(at ?r ?to)"],
"delete": ["(at ?r ?from)"],
"numeric": ["(decrease (battery-level ?r) 5.0)"],
"conditional": [
{
"condition": ["(has-payload ?r)"],
"effect": {
"add": ["(payload-delivered ?r)"],
"delete": [],
"numeric": []
}
}
],
"desc": "Drives rover from one location to another"
}
Fields:
- add (List[LogicalCondition]) - facts added by the action
- delete (List[LogicalCondition]) - facts deleted
- numeric (List[LogicalCondition]) - numeric changes (increase, decrease, assign)
- conditional (List[ConditionalEffect]) - conditional effects (PDDL 2.2+)
- desc (Optional[str])
ConditionalEffect¶
A when clause: when the condition holds, apply the effect.
{
"condition": ["(has-payload ?r)"],
"effect": {
"add": ["(payload-delivered)"],
"delete": [],
"numeric": []
},
"desc": "If it has a payload, deliver it"
}
Fields: condition (List[LogicalCondition]), effect (Dict[str, List[LogicalCondition]]), desc (Optional[str])
Action¶
A classical PDDL action (instantaneous).
{
"name": "drive",
"params": [
{"variable": "?r", "type": "rover"},
{"variable": "?from", "type": "location"},
{"variable": "?to", "type": "location"}
],
"preconditions": {
"conditions": ["(at ?r ?from)"]
},
"effects": {
"add": ["(at ?r ?to)"],
"delete": ["(at ?r ?from)"],
"numeric": ["(decrease (battery-level ?r) 10.0)"],
"conditional": []
},
"desc": "Drive rover between locations"
}
Fields: name (str), params (List[Parameter]), preconditions (ActionPrecondition), effects (ActionEffect), desc (Optional[str])
DurativeActionConditions¶
Temporal conditions split across at_start, over_all, and at_end.
{
"at_start": ["(at ?r ?from)"],
"over_all": [{"operator": "not", "condition": "(busy ?r)"}],
"at_end": [],
"desc": null
}
Fields: at_start (List[LogicalCondition]), over_all (List[LogicalCondition]), at_end (List[LogicalCondition]), desc (Optional[str])
DurativeActionEffect¶
Temporal effects split across at_start, at_end, and continuous (PDDL 2.1+).
{
"at_start": {
"add": ["(busy ?r)"],
"delete": [],
"numeric": [],
"conditional": []
},
"at_end": {
"add": ["(at ?r ?to)"],
"delete": ["(at ?r ?from)", "(busy ?r)"],
"numeric": [],
"conditional": []
},
"continuous": ["(decrease (battery ?r) (* #t 1.0))"],
"desc": null
}
Fields: at_start (ActionEffect), at_end (ActionEffect), continuous (List[LogicalCondition]), desc (Optional[str])
DurativeAction¶
A durative action (PDDL 2.1+) with duration, temporal conditions, and temporal effects.
{
"name": "navigate",
"params": [
{"variable": "?r", "type": "rover"},
{"variable": "?from", "type": "waypoint"},
{"variable": "?to", "type": "waypoint"}
],
"duration": ["(= ?duration 10.0)"],
"conditions": {
"at_start": ["(at ?r ?from)"],
"over_all": ["(has-power ?r)"],
"at_end": []
},
"effects": {
"at_start": {"add": ["(busy ?r)"], "delete": [], "numeric": [], "conditional": []},
"at_end": {"add": ["(at ?r ?to)"], "delete": ["(at ?r ?from)", "(busy ?r)"], "numeric": [], "conditional": []},
"continuous": []
},
"desc": "Navigate between waypoints over a fixed duration"
}
Fields: name (str), params (List[Parameter]), duration (List[str]), conditions (DurativeActionConditions), effects (DurativeActionEffect), desc (Optional[str])
Event¶
An instantaneous event in a PDDL+ process model - triggered automatically when its precondition becomes true.
{
"name": "battery-depleted",
"params": [{"variable": "?r", "type": "rover"}],
"preconditions": {
"conditions": ["(<= (battery-level ?r) 0)"]
},
"effects": {
"add": ["(dead ?r)"],
"delete": ["(has-power ?r)"],
"numeric": [],
"conditional": []
},
"desc": "Triggers when battery dies"
}
Fields: name (str), params (List[Parameter]), preconditions (ActionPrecondition), effects (ActionEffect), desc (Optional[str])
Process¶
A continuous process in a PDDL+ model - applies continuous effects over time while its precondition holds.
{
"name": "solar-charging",
"params": [{"variable": "?r", "type": "rover"}],
"preconditions": {
"conditions": ["(in-sun ?r)"]
},
"effects": {
"add": [],
"delete": [],
"numeric": ["(increase (battery-level ?r) (* #t 2.0))"],
"conditional": []
},
"desc": "Charges continuously in sun"
}
Fields: name (str), params (List[Parameter]), preconditions (ActionPrecondition), effects (ActionEffect), desc (Optional[str])
Constraint¶
A PDDL 3.0 trajectory constraint - a modal logical condition that must hold over the plan.
{
"condition": {
"operator": "always",
"condition": "(> (battery-level ?r) 0.0)"
},
"desc": "Battery must always be positive"
}
Fields: condition (LogicalCondition), desc (Optional[str])
DomainDetails¶
The root container for a complete PDDL domain. This is the top-level model returned when parsing an entire domain specification.
{
"name": "rover-domain",
"desc": "Planetary rover exploration domain",
"requirements": [{"name": ":strips"}, {"name": ":typing"}],
"types": [{"name": "rover", "parent": "object"}],
"constants": [],
"predicates": [{"name": "at", "params": [...]}],
"functions": [{"name": "battery-level", "params": [...]}],
"derived_predicates": [],
"actions": [{"name": "drive", "params": [...], ...}],
"durative_actions": [],
"events": [],
"processes": [],
"constraint": []
}
Fields: name (str), desc (Optional[str]), domain_pddl (Optional[str]),
requirements (List[Requirement]), types (List[PDDLType]), constants (List[Constant]),
predicates (List[Predicate]), functions (List[Function]),
derived_predicates (List[DerivedPredicate]), actions (List[Action]),
durative_actions (List[DurativeAction]), events (List[Event]),
processes (List[Process]), constraint (List[Constraint])
Problem Models¶
PDDLObject¶
A typed object instance in a PDDL problem.
{"name": "rover1", "type": "rover", "desc": "Instance of a rover"}
Fields: name (str), type (str), desc (Optional[str])
TimedFact¶
A timed initial literal (TIL) that triggers a fact at a specific time during plan execution.
{"time": 15.5, "fact": "(communications-blackout)", "desc": "Event triggers at t=15.5"}
Fields: time (float), fact (LogicalCondition), desc (Optional[str])
InitialState¶
The initial state of a problem, with optional timed facts.
{
"facts": [
"(at rover1 loc1)",
"(= (battery-level rover1) 100)"
],
"timed_facts": [{"time": 50.0, "fact": "(= (solar-flare-level) 80.0)"}],
"desc": "Starting state of the rover"
}
Fields: facts (List[LogicalCondition]), timed_facts (List[TimedFact]), desc (Optional[str])
GoalState¶
The goal conditions of a problem.
{
"conditions": [
"(at rover1 loc2)",
"(data-transmitted)"
],
"desc": "Target state"
}
Fields: conditions (List[LogicalCondition]), desc (Optional[str])
Metric¶
A plan optimization metric (PDDL 2.1+ / PDDL 3.0).
{
"optimization": "minimize",
"expression": "total-time",
"desc": "Minimize makespan"
}
Fields: optimization (str, one of minimize / maximize), expression (str), desc (Optional[str])
ProblemDetails¶
The root container for a complete PDDL problem.
{
"name": "prob1",
"domain_name": "rover_domain",
"objects": [{"name": "rover1", "type": "rover"}],
"initial_state": {"facts": [...], "timed_facts": [...]},
"goal_state": {"conditions": [...]},
"constraint": [],
"metric": {"optimization": "minimize", "expression": "total-time"}
}
Fields: name (str), domain_name (str), desc (Optional[str]),
problem_pddl (Optional[str]), objects (List[PDDLObject]),
initial_state (InitialState), goal_state (GoalState),
constraint (List[Constraint]), metric (Optional[Metric])