2 changed files with 144 additions and 0 deletions
@ -0,0 +1,140 @@ |
|||||
|
def format_name(name): |
||||
|
return name.replace(' ', '_').replace('.', '').replace("'", '') |
||||
|
|
||||
|
def generate_pddl_domain(): |
||||
|
# Define the types, predicates, and action as shown above |
||||
|
domain_pddl = """ |
||||
|
(define (domain pokemon) |
||||
|
(:requirements :strips :typing :equality :quantified-preconditions :conditional-effects) |
||||
|
(:types |
||||
|
location |
||||
|
condition |
||||
|
) |
||||
|
(:predicates |
||||
|
(at ?loc - location) |
||||
|
(connected ?from ?to - location) |
||||
|
(has ?cond - condition) |
||||
|
(grants ?loc - location ?cond - condition) |
||||
|
(requires ?from ?to - location ?cond - condition) |
||||
|
(requires_grant ?loc - location ?cond - condition ?req - condition) |
||||
|
(visited ?loc - location) |
||||
|
) |
||||
|
(:action move |
||||
|
:parameters (?from ?to - location) |
||||
|
:precondition (and |
||||
|
(at ?from) |
||||
|
(connected ?from ?to) |
||||
|
; Remove (not (visited ?to)) if re-visiting is allowed |
||||
|
; Universal preconditions for required conditions |
||||
|
(forall (?cond - condition) |
||||
|
(imply (requires ?from ?to ?cond) (has ?cond)) |
||||
|
) |
||||
|
) |
||||
|
:effect (and |
||||
|
(at ?to) |
||||
|
(not (at ?from)) |
||||
|
(visited ?to) |
||||
|
) |
||||
|
) |
||||
|
(:action acquire |
||||
|
:parameters (?loc - location ?cond - condition) |
||||
|
:precondition (and |
||||
|
(at ?loc) |
||||
|
(grants ?loc ?cond) |
||||
|
(not (has ?cond)) |
||||
|
; Universal preconditions for required grants |
||||
|
(forall (?req - condition) |
||||
|
(imply (requires_grant ?loc ?cond ?req) (has ?req)) |
||||
|
) |
||||
|
) |
||||
|
:effect (and |
||||
|
(has ?cond) |
||||
|
) |
||||
|
) |
||||
|
) |
||||
|
""" |
||||
|
with open('pokemon_domain.pddl', 'w') as f: |
||||
|
f.write(domain_pddl) |
||||
|
|
||||
|
def generate_pddl_problem(G): |
||||
|
# Extract objects, init, and goal |
||||
|
locations = set() |
||||
|
conditions = set() |
||||
|
connections = [] |
||||
|
grants = [] |
||||
|
requirements = [] |
||||
|
requires_grant = [] |
||||
|
|
||||
|
# Gather conditions from node grants and edge requirements |
||||
|
for node, attrs in G.nodes(data=True): |
||||
|
node_formatted = format_name(node) |
||||
|
locations.add(node_formatted) |
||||
|
grants_conditions = attrs.get('grants_conditions', []) |
||||
|
for grant in grants_conditions: |
||||
|
condition = format_name(grant['condition']) |
||||
|
conditions.add(condition) |
||||
|
grants.append((node_formatted, condition)) |
||||
|
required_conditions = grant.get('required_conditions', []) |
||||
|
for req in required_conditions: |
||||
|
req_condition = format_name(req) |
||||
|
conditions.add(req_condition) |
||||
|
requires_grant.append((node_formatted, condition, req_condition)) |
||||
|
|
||||
|
for u, v, attrs in G.edges(data=True): |
||||
|
u_formatted = format_name(u) |
||||
|
v_formatted = format_name(v) |
||||
|
locations.update([u_formatted, v_formatted]) |
||||
|
# Add both directions for bidirectional movement |
||||
|
connections.append((u_formatted, v_formatted)) |
||||
|
connections.append((v_formatted, u_formatted)) # Add reverse connection |
||||
|
|
||||
|
edge_condition = attrs.get('condition') |
||||
|
if edge_condition: |
||||
|
if isinstance(edge_condition, list): |
||||
|
for cond in edge_condition: |
||||
|
cond_formatted = format_name(cond) |
||||
|
conditions.add(cond_formatted) |
||||
|
requirements.append((u_formatted, v_formatted, cond_formatted)) |
||||
|
requirements.append((v_formatted, u_formatted, cond_formatted)) # Reverse |
||||
|
else: |
||||
|
cond_formatted = format_name(edge_condition) |
||||
|
conditions.add(cond_formatted) |
||||
|
requirements.append((u_formatted, v_formatted, cond_formatted)) |
||||
|
requirements.append((v_formatted, u_formatted, cond_formatted)) # Reverse |
||||
|
|
||||
|
# Prepare the PDDL problem file content |
||||
|
problem_pddl = "(define (problem pokemon_problem)\n" |
||||
|
problem_pddl += " (:domain pokemon)\n" |
||||
|
|
||||
|
# Objects |
||||
|
problem_pddl += " (:objects\n" |
||||
|
problem_pddl += " " + " ".join(sorted(locations)) + " - location\n" |
||||
|
problem_pddl += " " + " ".join(sorted(conditions)) + " - condition\n" |
||||
|
problem_pddl += " )\n" |
||||
|
|
||||
|
# Initial state |
||||
|
problem_pddl += " (:init\n" |
||||
|
problem_pddl += f" (at {format_name('New Bark Town')})\n" |
||||
|
for u, v in connections: |
||||
|
problem_pddl += f" (connected {u} {v})\n" |
||||
|
for loc, cond in grants: |
||||
|
problem_pddl += f" (grants {loc} {cond})\n" |
||||
|
for u, v, cond in requirements: |
||||
|
problem_pddl += f" (requires {u} {v} {cond})\n" |
||||
|
for loc, cond, req in requires_grant: |
||||
|
problem_pddl += f" (requires_grant {loc} {cond} {req})\n" |
||||
|
problem_pddl += " )\n" |
||||
|
|
||||
|
# Goal state |
||||
|
badges = ['Zephyr Badge', 'Hive Badge', 'Plain Badge', 'Fog Badge', 'Storm Badge', 'Mineral Badge', 'Glacier Badge', 'Rising Badge'] |
||||
|
problem_pddl += " (:goal\n" |
||||
|
problem_pddl += " (and\n" |
||||
|
problem_pddl += f" (at {format_name('Indigo Plateau')})\n" |
||||
|
for badge in badges: |
||||
|
problem_pddl += f" (has {format_name(badge)})\n" |
||||
|
problem_pddl += " )\n" |
||||
|
problem_pddl += " )\n" |
||||
|
problem_pddl += ")\n" |
||||
|
|
||||
|
with open('pokemon_problem.pddl', 'w') as f: |
||||
|
f.write(problem_pddl) |
||||
Loading…
Reference in new issue