17. MA-PDDL I/O Example MA-Logistic
This notebook will show the possible interations between the ma-pddl language and the unified_planning usage.
17.1. Setup
We start by installing the library with PIP
[ ]:
!pip install --pre unified-planning[fmap]
[ ]:
from unified_planning.shortcuts import *
from unified_planning.model.multi_agent import *
from collections import namedtuple
from unified_planning.io.ma_pddl_writer import MAPDDLWriter
problem = MultiAgentProblem("ma-logistic")
truck1 = Agent("truck1", problem)
truck2 = Agent("truck2", problem)
airplane = Agent("airplane", problem)
object = UserType("object")
location = UserType("location", object)
vehicle = UserType("vehicle", object)
package = UserType("package", object)
city = UserType("city", object)
airport = UserType("airport", location)
truck_ = UserType("truck_", vehicle)
airplane_ = UserType("airplane_", vehicle)
pos = Fluent("pos", location=location)
at = Fluent("at", BoolType(), object=object, location=location)
In = Fluent("in", BoolType(), package=package, vehicle=vehicle)
on = Fluent("on", BoolType(), object=object)
in_city = Fluent("in_city", BoolType(), location=location, city=city)
truck1.add_public_fluent(pos, default_initial_value=False)
truck1.add_private_fluent(in_city, default_initial_value=False)
truck1.add_public_fluent(on, default_initial_value=False)
truck2.add_public_fluent(pos, default_initial_value=False)
truck2.add_private_fluent(in_city, default_initial_value=False)
truck2.add_public_fluent(on, default_initial_value=False)
airplane.add_public_fluent(pos, default_initial_value=False)
airplane.add_public_fluent(on, default_initial_value=False)
problem.ma_environment.add_fluent(at, default_initial_value=False)
problem.ma_environment.add_fluent(In, default_initial_value=False)
load_truck = InstantaneousAction("load_truck", loc=location, obj=package)
obj = load_truck.parameter("obj")
loc = load_truck.parameter("loc")
load_truck.add_precondition(at(obj, loc))
load_truck.add_precondition(pos(loc))
load_truck.add_effect(at(obj, loc), False)
load_truck.add_effect(on(obj), True)
unload_truck = InstantaneousAction("unload_truck", obj=package, loc=location)
obj = unload_truck.parameter("obj")
loc = unload_truck.parameter("loc")
unload_truck.add_precondition(pos(loc))
unload_truck.add_precondition(on(obj))
unload_truck.add_effect(on(obj), False)
unload_truck.add_effect(at(obj, loc), True)
drive_truck = InstantaneousAction("drive_truck", loc_from=location, loc_to=location, city_=city)
loc_from = drive_truck.parameter("loc_from")
loc_to = drive_truck.parameter("loc_to")
city_ = drive_truck.parameter("city_")
drive_truck.add_precondition(pos(loc_from))
drive_truck.add_precondition(in_city(loc_from, city_))
drive_truck.add_precondition(in_city(loc_to, city_))
drive_truck.add_effect(pos(loc_from), False)
drive_truck.add_effect(pos(loc_to), True)
load_airplane = InstantaneousAction("load_airplane", loc = airport, obj=package)
loc = load_airplane.parameter("loc")
obj = load_airplane.parameter("obj")
load_airplane.add_precondition(at(obj, loc))
load_airplane.add_precondition(pos(loc))
load_airplane.add_effect(at(obj, loc), False)
load_airplane.add_effect(on(obj), True)
unload_airplane = InstantaneousAction("unload_airplane", loc = airport, obj=package)
loc = load_airplane.parameter("loc")
obj = load_airplane.parameter("obj")
unload_airplane.add_precondition(on(obj))
unload_airplane.add_precondition(pos(loc))
unload_airplane.add_effect(on(obj), False)
unload_airplane.add_effect(at(obj, loc), True)
fly_airplane = InstantaneousAction("fly_airplane", loc_from=airport, loc_to=airport)
loc_from = fly_airplane.parameter("loc_from")
loc_to = fly_airplane.parameter("loc_to")
fly_airplane.add_precondition(pos(loc_from))
fly_airplane.add_effect(pos(loc_from), False)
fly_airplane.add_effect(pos(loc_to), True)
truck1.add_action(drive_truck)
truck1.add_action(unload_truck)
truck1.add_action(load_truck)
truck2.add_action(drive_truck)
truck2.add_action(unload_truck)
truck2.add_action(load_truck)
airplane.add_action(load_airplane)
airplane.add_action(unload_airplane)
airplane.add_action(fly_airplane)
problem.add_agent(truck1)
problem.add_agent(truck2)
problem.add_agent(airplane)
#problem
obj21 = Object("obj21", package)
obj22 = Object("obj22", package)
obj23 = Object("obj23", package)
obj11 = Object("obj11", package)
obj13 = Object("obj13", package)
obj12 = Object("obj12", package)
apt2 = Object("apt2", airport)
apt1 = Object("apt1", airport)
pos1 = Object("pos1", location)
cit1 = Object("cit1", city)
pos2 = Object("pos2", location)
cit2 = Object("cit2", city)
problem.add_object(obj21)
problem.add_object(obj22)
problem.add_object(obj23)
problem.add_object(obj11)
problem.add_object(obj13)
problem.add_object(obj12)
problem.add_object(apt2)
problem.add_object(apt1)
problem.add_object(pos1)
problem.add_object(cit1)
problem.add_object(pos2)
problem.add_object(cit2)
problem.set_initial_value(Dot(truck1, pos(pos1)), True)
problem.set_initial_value(at(obj11, pos1), True)
problem.set_initial_value(at(obj12, pos1), True)
problem.set_initial_value(at(obj13, pos1), True)
problem.set_initial_value(Dot(truck1, in_city(pos1, cit1)), True)
problem.set_initial_value(Dot(truck1, in_city(apt1, cit1)), True)
problem.set_initial_value(Dot(truck1, pos(pos1)), True)
problem.set_initial_value(Dot(truck2, pos(pos2)), True)
problem.set_initial_value(at(obj21, pos2), True)
problem.set_initial_value(at(obj22, pos2), True)
problem.set_initial_value(at(obj23, pos2), True)
problem.set_initial_value(Dot(truck2, in_city(pos2, cit2)), True)
problem.set_initial_value(Dot(truck2, in_city(apt2, cit2)), True)
problem.set_initial_value(Dot(truck2, pos(pos2)), True)
problem.set_initial_value(Dot(airplane, pos(apt2)), True)
problem.set_initial_value(at(obj11, pos1), True)
problem.set_initial_value(at(obj12, pos1), True)
problem.set_initial_value(at(obj13, pos1), True)
problem.set_initial_value(Dot(airplane, pos(apt2)), True)
problem.add_goal(at(obj11, apt1))
problem.add_goal(at(obj23, pos1))
problem.add_goal(at(obj13, apt1))
problem.add_goal(at(obj21, pos1))
w = MAPDDLWriter(problem)
w.write_ma_domain('logistic')
w.write_ma_problem('logistic')
[ ]:
print(problem)
problem name = ma-logistic
types = [object, location - object, city - object, package - object, vehicle - object, airport - location]
environment fluents = [
bool at[object=object, location=location - object]
bool in[package=package - object, vehicle=vehicle - object]
]
agents = [
Agent name = truck1
private fluents = [
bool in_city[location=location - object, city=city - object]
]
public fluents = [
bool pos[location=location - object]
bool on[object=object]
]
actions = [
action drive_truck(location - object loc_from, location - object loc_to, city - object city_) {
preconditions = [
pos(loc_from)
in_city(loc_from, city_)
in_city(loc_to, city_)
]
effects = [
pos(loc_from) := false
pos(loc_to) := true
]
}
action unload_truck(package - object obj, location - object loc) {
preconditions = [
pos(loc)
on(obj)
]
effects = [
on(obj) := false
at(obj, loc) := true
]
}
action load_truck(location - object loc, package - object obj) {
preconditions = [
at(obj, loc)
pos(loc)
]
effects = [
at(obj, loc) := false
on(obj) := true
]
}
]
Agent name = truck2
private fluents = [
bool in_city[location=location - object, city=city - object]
]
public fluents = [
bool pos[location=location - object]
bool on[object=object]
]
actions = [
action drive_truck(location - object loc_from, location - object loc_to, city - object city_) {
preconditions = [
pos(loc_from)
in_city(loc_from, city_)
in_city(loc_to, city_)
]
effects = [
pos(loc_from) := false
pos(loc_to) := true
]
}
action unload_truck(package - object obj, location - object loc) {
preconditions = [
pos(loc)
on(obj)
]
effects = [
on(obj) := false
at(obj, loc) := true
]
}
action load_truck(location - object loc, package - object obj) {
preconditions = [
at(obj, loc)
pos(loc)
]
effects = [
at(obj, loc) := false
on(obj) := true
]
}
]
Agent name = airplane
private fluents = [
]
public fluents = [
bool pos[location=location - object]
bool on[object=object]
]
actions = [
action load_airplane(airport - location loc, package - object obj) {
preconditions = [
at(obj, loc)
pos(loc)
]
effects = [
at(obj, loc) := false
on(obj) := true
]
}
action unload_airplane(airport - location loc, package - object obj) {
preconditions = [
on(obj)
pos(loc)
]
effects = [
on(obj) := false
at(obj, loc) := true
]
}
action fly_airplane(airport - location loc_from, airport - location loc_to) {
preconditions = [
pos(loc_from)
]
effects = [
pos(loc_from) := false
pos(loc_to) := true
]
}
]
]
objects = [
object: [obj21, obj22, obj23, obj11, obj13, obj12, apt2, apt1, pos1, cit1, pos2, cit2]
location - object: [apt2, apt1, pos1, pos2]
city - object: [cit1, cit2]
package - object: [obj21, obj22, obj23, obj11, obj13, obj12]
vehicle - object: []
airport - location: [apt2, apt1]
]
initial values = [
truck1.pos(pos1) := true
at(obj11, pos1) := true
at(obj12, pos1) := true
at(obj13, pos1) := true
truck1.in_city(pos1, cit1) := true
truck1.in_city(apt1, cit1) := true
truck2.pos(pos2) := true
at(obj21, pos2) := true
at(obj22, pos2) := true
at(obj23, pos2) := true
truck2.in_city(pos2, cit2) := true
truck2.in_city(apt2, cit2) := true
airplane.pos(apt2) := true
at(obj21, apt2) := false
at(obj22, apt2) := false
at(obj23, apt2) := false
at(obj11, apt2) := false
at(obj13, apt2) := false
at(obj12, apt2) := false
at(apt2, apt2) := false
at(apt1, apt2) := false
at(pos1, apt2) := false
at(cit1, apt2) := false
at(pos2, apt2) := false
at(cit2, apt2) := false
at(obj21, apt1) := false
at(obj22, apt1) := false
at(obj23, apt1) := false
at(obj11, apt1) := false
at(obj13, apt1) := false
at(obj12, apt1) := false
at(apt2, apt1) := false
at(apt1, apt1) := false
at(pos1, apt1) := false
at(cit1, apt1) := false
at(pos2, apt1) := false
at(cit2, apt1) := false
at(obj21, pos1) := false
at(obj22, pos1) := false
at(obj23, pos1) := false
at(apt2, pos1) := false
at(apt1, pos1) := false
at(pos1, pos1) := false
at(cit1, pos1) := false
at(pos2, pos1) := false
at(cit2, pos1) := false
at(obj11, pos2) := false
at(obj13, pos2) := false
at(obj12, pos2) := false
at(apt2, pos2) := false
at(apt1, pos2) := false
at(pos1, pos2) := false
at(cit1, pos2) := false
at(pos2, pos2) := false
at(cit2, pos2) := false
truck1.pos(apt2) := false
truck1.pos(apt1) := false
truck1.pos(pos2) := false
truck1.in_city(apt2, cit1) := false
truck1.in_city(pos2, cit1) := false
truck1.in_city(apt2, cit2) := false
truck1.in_city(apt1, cit2) := false
truck1.in_city(pos1, cit2) := false
truck1.in_city(pos2, cit2) := false
truck1.on(obj21) := false
truck1.on(obj22) := false
truck1.on(obj23) := false
truck1.on(obj11) := false
truck1.on(obj13) := false
truck1.on(obj12) := false
truck1.on(apt2) := false
truck1.on(apt1) := false
truck1.on(pos1) := false
truck1.on(cit1) := false
truck1.on(pos2) := false
truck1.on(cit2) := false
truck2.pos(apt2) := false
truck2.pos(apt1) := false
truck2.pos(pos1) := false
truck2.in_city(apt2, cit1) := false
truck2.in_city(apt1, cit1) := false
truck2.in_city(pos1, cit1) := false
truck2.in_city(pos2, cit1) := false
truck2.in_city(apt1, cit2) := false
truck2.in_city(pos1, cit2) := false
truck2.on(obj21) := false
truck2.on(obj22) := false
truck2.on(obj23) := false
truck2.on(obj11) := false
truck2.on(obj13) := false
truck2.on(obj12) := false
truck2.on(apt2) := false
truck2.on(apt1) := false
truck2.on(pos1) := false
truck2.on(cit1) := false
truck2.on(pos2) := false
truck2.on(cit2) := false
airplane.pos(apt1) := false
airplane.pos(pos1) := false
airplane.pos(pos2) := false
airplane.on(obj21) := false
airplane.on(obj22) := false
airplane.on(obj23) := false
airplane.on(obj11) := false
airplane.on(obj13) := false
airplane.on(obj12) := false
airplane.on(apt2) := false
airplane.on(apt1) := false
airplane.on(pos1) := false
airplane.on(cit1) := false
airplane.on(pos2) := false
airplane.on(cit2) := false
]
goals = [
at(obj11, apt1)
at(obj23, pos1)
at(obj13, apt1)
at(obj21, pos1)
]
17.2. MA-PDDL Writer
As the name suggests, MAPDDLWriter
offers the capability of dumping a unified_planning MultiAgentProblem
in ma-pddl.
There are 3 possible usages of the MAPDDLWriter
:
printing ma-pddl domain and problem in a different file for each agent (factored domains)
getting ma-pddl domain and problem for each agent as a python str
printing ma-pddl domain and problem for each agent to
STDOUT
17.3. Writing to files
To write the ma-pddl equivalent of a unified_planning MultiAgentProblem
to a file we use the MAPDDLWriter.write_ma_domain
and MAPDDLWriter.write_ma_problem
methods.
[ ]:
w = MAPDDLWriter(problem)
w.write_ma_domain('ma_logistic_directory')
w.write_ma_problem('ma_logistic_directory')
17.3.1. Getting domains and problems as a python strings
To get the ma-pddl equivalent of a unified_planning MultiAgentProblem
as a python strings we use the MAPDDLWriter.get_ma_domain_agent('name_of_agent')
and MAPDDLWriter.get_ma_problem_agent('name_of_agent')
methods. In this way we can get the domain and problem of a particular agent.
[ ]:
w.get_ma_domain_agent('truck1')
w.get_ma_problem_agent('airplane')
'(define (problem ma_logistic-problem)\n (:domain ma_logistic-domain)\n (:objects\n pos1 pos2 - location\n cit1 cit2 - city\n obj21 obj22 obj23 obj11 obj13 obj12 - package\n apt2 apt1 - airport\n truck1 - truck1_type\n truck2 - truck2_type\n airplane - airplane_type\n )\n (:init\n (a_pos truck1 pos1)\n (at_ obj11 pos1)\n (at_ obj12 pos1)\n (at_ obj13 pos1)\n (a_pos truck2 pos2)\n (at_ obj21 pos2)\n (at_ obj22 pos2)\n (at_ obj23 pos2)\n (a_pos airplane apt2))\n (:goal (and (at_ obj11 apt1) (at_ obj23 pos1) (at_ obj13 apt1) (at_ obj21 pos1)))\n)'
###Printing domain and problem to STDOUT
To print the pddl equivalent of a unified_planning Problem
to STDOUT
we use the MAPDDLWriter.print_ma_domain_agent('name_of_agent')
and MAPDDLWriter.print_ma_problem_agent('name_of_agent')
methods.
[ ]:
w.print_ma_domain_agent('truck1')
w.print_ma_problem_agent('airplane')
(define (domain ma_logistic-domain)
(:requirements :factored-privacy :typing)
(:types
object_ ag - object
truck1_type truck2_type airplane_type - ag
location city package vehicle - object_
airport - location
)
(:predicates
(at_ ?object - object_ ?location - location)
(in ?package - package ?vehicle - vehicle)
(a_pos ?agent - ag ?location - location)
(a_on ?agent - ag ?object - object_)
(:private
(a_in_city ?agent - ag ?location - location ?city - city)))
(:action drive_truck
:parameters ( ?truck1 - truck1_type ?loc_from - location ?loc_to - location ?city_ - city)
:precondition (and
(a_pos ?truck1 ?loc_from)
(a_in_city ?truck1 ?loc_from ?city_)
(a_in_city ?truck1 ?loc_to ?city_)
)
:effect (and
(not (a_pos ?truck1 ?loc_from))
(a_pos ?truck1 ?loc_to)
))
(:action unload_truck
:parameters ( ?truck1 - truck1_type ?obj - package ?loc - location)
:precondition (and
(a_pos ?truck1 ?loc)
(a_on ?truck1 ?obj)
)
:effect (and
(not (a_on ?truck1 ?obj))
(at_ ?obj ?loc)
))
(:action load_truck
:parameters ( ?truck1 - truck1_type ?loc - location ?obj - package)
:precondition (and
(at_ ?obj ?loc)
(a_pos ?truck1 ?loc)
)
:effect (and
(not (at_ ?obj ?loc))
(a_on ?truck1 ?obj)
))
)
(define (problem ma_logistic-problem)
(:domain ma_logistic-domain)
(:objects
pos1 pos2 - location
cit1 cit2 - city
obj21 obj22 obj23 obj11 obj13 obj12 - package
apt2 apt1 - airport
truck1 - truck1_type
truck2 - truck2_type
airplane - airplane_type
)
(:init
(a_pos truck1 pos1)
(at_ obj11 pos1)
(at_ obj12 pos1)
(at_ obj13 pos1)
(a_pos truck2 pos2)
(at_ obj21 pos2)
(at_ obj22 pos2)
(at_ obj23 pos2)
(a_pos airplane apt2))
(:goal (and (at_ obj11 apt1) (at_ obj23 pos1) (at_ obj13 apt1) (at_ obj21 pos1)))
)