Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
Cranial-XIX committed Apr 25, 2023
0 parents commit 1853845
Show file tree
Hide file tree
Showing 4,426 changed files with 1,924,634 additions and 0 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
pddl
openai-quickstart-python
data/openai_keys.txt
sas_plan
Condor*
*.pyc
downward
openai-quickstart-node/
trainlogs
clean.sh
check.sh
condor*
keys
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "downward"]
path = downward
url = https://github.com/aibasel/downward.git
67 changes: 67 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# LLM+P: Large Language Model Meets Classical Planners
This repo contains the source code for making plans based on problems decribed by natural language.

## Dependency

1. Install OpenAI GPT [API](https://platform.openai.com/docs/quickstart/build-your-application). Remember to put openai_keys under the ```data``` folder.

2. Install [fast-downward](https://drive.google.com/file/d/16HlP14IN06asIXYAZ8RHR1P7-cEYwhA6/view)

## Running Code
To run a for a specific task in a specific domain using a specific method:
```
python main.py --domain DOMAIN --method METHOD --task TASK_ID
```
`DOMAIN` is selected from
```[barman, blocksworld, floortile, grippers, storage, termes, tyreworld]```

`METHOD` is selected from
```[llm_ic_pddl_planner, llm_pddl_planner, llm_planner, llm_ic_planner]```

Alternatively, you can just use:
```
bash run.sh DOMAIN METHOD TASK_ID
```

### The File Hierarchy:
```
llm-pddl
└─main.py (the main python script)
└─keys
└─ openai_keys.txt (you should place your openai keys here, one line each)
└─domains (the generated domain files)
└─ barman
└─ description_geneator.py (generating natural language description)
└─ p_example.nl (example natural language)
└─ p_example.pddl (example problem pddl file)
└─ domain.pddl (the shared domain.pddl file for all problems)
└─ xxx.nl (task natural language description)
└─ xxx.pddl (ground-truth problem pddl, might not be used)
└─ blocksworld
└─ floortile
└─ grippers
└─ storage
└─ termes
└─ tyreworld
└─problems (the generated problem pddl files)
└─ llm (empty, since llm -> plan does not generate pddl)
└─ llm_ic (empty, since llm + context -> plan does not generate pddl)
└─ llm_pddl (baseline 2: llm -> p.pddl)
└─ llm_ic_pddl (ours: llm + context -> p.pddl)
└─ barman
└─ ...
└─plans (the tmp folder for storing raw solutions found by fast-downward)
└─ llm (empty, since llm -> plan does not generate raw plans)
└─ llm_ic (empty, since llm + context -> plan does not generate raw plans)
└─ llm_pddl (baseline 2: llm -> p.pddl)
└─ llm_ic_pddl (ours: llm + context -> p.pddl)
└─ barman
└─ ...
└─results (the final plan in natural language)
└─ llm (baseline 1: llm -> plan)
└─ llm_ic (baseline 3: llm + context -> plan)
└─ llm_pddl (baseline 2: llm -> p.pddl)
└─ llm_ic_pddl (ours: llm + context -> p.pddl)
└─ barman
└─ ...
```
65 changes: 65 additions & 0 deletions domains/barman/description_generator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import os
import sys
from collections import namedtuple
import glob

# PDDLStream https://github.com/caelan/pddlstream/blob/526b450a7d3913d3833e1413df416efa7e71ca6a/pddlstream/algorithms/downward.py
def find_build(fd_path):
for release in ['release', 'release64', 'release32']: # TODO: list the directory
path = os.path.join(fd_path, 'builds/{}/'.format(release))
if os.path.exists(path):
return path
# TODO: could also just automatically compile
raise RuntimeError('Please compile FastDownward first [.../pddlstream$ ./downward/build.py]')

directory = os.path.dirname(os.path.abspath(__file__))
FD_PATH = os.path.join(directory, '../../downward')
TRANSLATE_PATH = os.path.join(find_build(FD_PATH), 'bin/translate')
sys.path.append(TRANSLATE_PATH)

from pddl_parser import pddl_file

Domain = namedtuple('Domain', ['name', 'requirements', 'types', 'type_dict', 'constants',
'predicates', 'predicate_dict', 'functions', 'actions', 'axioms'])
Problem = namedtuple('Problem', ['task_name', 'task_domain_name', 'task_requirements',
'objects', 'init', 'goal', 'use_metric'])

domain_file = "domain.pddl"
problem_path = os.path.join(directory, 'p*.pddl')
problem_files = glob.glob(problem_path)

for problem_file in problem_files:

task = pddl_file.open(domain_file, problem_file)
count = {}
description = ""
for obj in task.objects:
if obj.type_name not in count.keys():
count[obj.type_name] = 0
count[obj.type_name] += 1

description += f'You have {count["shaker"]} shaker with {count["level"]} levels, {count["shot"]} shot glasses, {count["dispenser"]} dispensers for {count["ingredient"]} ingredients. \n'
description += "The shaker and shot glasses are clean, empty, and on the table. Your left and right hands are empty. \n"

cocktails = {obj.name: [0, 0] for obj in task.objects if obj.type_name == "cocktail"}
for atom in task.init:
if "cocktail-part1" in atom.predicate:
cocktails[atom.args[0]][0] = atom.args[1]
if "cocktail-part2" in atom.predicate:
cocktails[atom.args[0]][1] = atom.args[1]

for cocktail in cocktails.keys():
description += f"The first ingredient of {cocktail} is {cocktails[cocktail][0]}. "
description += f"The second ingredient of {cocktail} is {cocktails[cocktail][1]}. \n"

if len(task.goal.parts) > 0:
goals = task.goal.parts
else:
goals = [task.goal]
description += f"Your goal is to make {len(goals)} cocktails. \n"
for goal in goals:
description += f"{goal.args[0]} contains {goal.args[1]}. "

nl_file = os.path.splitext(problem_file)[0] + ".nl"
with open(nl_file, 'w') as f:
f.write(description)
34 changes: 34 additions & 0 deletions domains/barman/domain.nl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
You are a robot barman that manipulates drink dispensers, shot glasses and a shaker. You have two hands. The goal is to find a plan that serves a desired set of drinks. Here are the actions you can do

Grasp a container
Leave a container on the table
Fill a shot glass with an ingredient
Refill a shot glass with an ingredient
Empty a shot glass
Clean a shot glass
Pour an ingredient from a shot glass to a clean shaker
Pour an ingredient from a shot glass to a used shaker
Empty a shaker
Clean a shaker
Shake a cocktail in a shaker
Pour from a shaker to a shot glass

You have the following restrictions on your actions:
You can only grasp a container if your hand is empty and it is on the table.
You can only leave a container if you are holding it.
You can only fill a shot glass if you are holding the shot glass, your other hand is empty, the shot glass is empty and clean.
You can only refill a shot glass if you are holding the shot glass, your other hand is empty, the shot glass is empty and has contained the saree ingredient before.
You can only empty a shot glass if you are holding the shot glass and it contains a beverage.
You can only pour from a shot glass to a clean shaker if you are holding the shot glass, the shot glass contains an ingredient, and the shaker is empty and clean.
You can only pour from a shot glass to a used shaker if you are holding the shot glass, the shot glass contains an ingredient, the shaker is unshaked and at a level not full.
You can only empty a shaker if you are holding the shaker and the shaker contains a shaked beverage.
You can only clean a shaker if you are holding the shaker, your other hand is empty, and the shaker is empty.
You can only shake a cocktail if you are holding the shaker, your other hand is empty, the shaker is unshaked, and the shaker contains two ingredients, and both ingredients are parts of a cocktail.
You can only pour from a shaker to a shot glass if you are holding the shaker, the shaker contains the cocktail, the shaker is shaked, and the shot glass is empty and clean.

Once you grasp a container, you are holding the container and the container is not on the table.
Once you leave a container on the table, your hand become empty.
Once you pour an ingredient from a shot glass to a shaker, the shaker contains the ingredient and is at one level above the previous level, and the shot glass becomes empty.
Once you empty a shaker, the shaker is at the empty level.
Once you shake, the two ingredients in the shaker become a cocktail.
Once you pour from a shaker to a shot glass, the shot glass contains the beverage in the shaker, the shot glass is no longer clean and empty, and the shaker is at one level below the previous level.
155 changes: 155 additions & 0 deletions domains/barman/domain.pddl
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
(define (domain barman)
(:requirements :strips :typing)
(:types hand level beverage dispenser container - object
ingredient cocktail - beverage
shot shaker - container)
(:predicates (ontable ?c - container)
(holding ?h - hand ?c - container)
(handempty ?h - hand)
(empty ?c - container)
(contains ?c - container ?b - beverage)
(clean ?c - container)
(used ?c - container ?b - beverage)
(dispenses ?d - dispenser ?i - ingredient)
(shaker-empty-level ?s - shaker ?l - level)
(shaker-level ?s - shaker ?l - level)
(next ?l1 ?l2 - level)
(unshaked ?s - shaker)
(shaked ?s - shaker)
(cocktail-part1 ?c - cocktail ?i - ingredient)
(cocktail-part2 ?c - cocktail ?i - ingredient))

(:action grasp
:parameters (?h - hand ?c - container)
:precondition (and (ontable ?c) (handempty ?h))
:effect (and (not (ontable ?c))
(not (handempty ?h))
(holding ?h ?c)))

(:action leave
:parameters (?h - hand ?c - container)
:precondition (holding ?h ?c)
:effect (and (not (holding ?h ?c))
(handempty ?h)
(ontable ?c)))

(:action fill-shot
:parameters (?s - shot ?i - ingredient ?h1 ?h2 - hand ?d - dispenser)
:precondition (and (holding ?h1 ?s)
(handempty ?h2)
(dispenses ?d ?i)
(empty ?s)
(clean ?s))
:effect (and (not (empty ?s))
(contains ?s ?i)
(not (clean ?s))
(used ?s ?i)))


(:action refill-shot
:parameters (?s - shot ?i - ingredient ?h1 ?h2 - hand ?d - dispenser)
:precondition (and (holding ?h1 ?s)
(handempty ?h2)
(dispenses ?d ?i)
(empty ?s)
(used ?s ?i))
:effect (and (not (empty ?s))
(contains ?s ?i)))

(:action empty-shot
:parameters (?h - hand ?p - shot ?b - beverage)
:precondition (and (holding ?h ?p)
(contains ?p ?b))
:effect (and (not (contains ?p ?b))
(empty ?p)))

(:action clean-shot
:parameters (?s - shot ?b - beverage ?h1 ?h2 - hand)
:precondition (and (holding ?h1 ?s)
(handempty ?h2)
(empty ?s)
(used ?s ?b))
:effect (and (not (used ?s ?b))
(clean ?s)))

(:action pour-shot-to-clean-shaker
:parameters (?s - shot ?i - ingredient ?d - shaker ?h1 - hand ?l ?l1 - level)
:precondition (and (holding ?h1 ?s)
(contains ?s ?i)
(empty ?d)
(clean ?d)
(shaker-level ?d ?l)
(next ?l ?l1))
:effect (and (not (contains ?s ?i))
(empty ?s)
(contains ?d ?i)
(not (empty ?d))
(not (clean ?d))
(unshaked ?d)
(not (shaker-level ?d ?l))
(shaker-level ?d ?l1)))


(:action pour-shot-to-used-shaker
:parameters (?s - shot ?i - ingredient ?d - shaker ?h1 - hand ?l ?l1 - level)
:precondition (and (holding ?h1 ?s)
(contains ?s ?i)
(unshaked ?d)
(shaker-level ?d ?l)
(next ?l ?l1))
:effect (and (not (contains ?s ?i))
(contains ?d ?i)
(empty ?s)
(not (shaker-level ?d ?l))
(shaker-level ?d ?l1)))

(:action empty-shaker
:parameters (?h - hand ?s - shaker ?b - cocktail ?l ?l1 - level)
:precondition (and (holding ?h ?s)
(contains ?s ?b)
(shaked ?s)
(shaker-level ?s ?l)
(shaker-empty-level ?s ?l1))
:effect (and (not (shaked ?s))
(not (shaker-level ?s ?l))
(shaker-level ?s ?l1)
(not (contains ?s ?b))
(empty ?s)))

(:action clean-shaker
:parameters (?h1 ?h2 - hand ?s - shaker)
:precondition (and (holding ?h1 ?s)
(handempty ?h2)
(empty ?s))
:effect (and (clean ?s)))

(:action shake
:parameters (?b - cocktail ?d1 ?d2 - ingredient ?s - shaker ?h1 ?h2 - hand)
:precondition (and (holding ?h1 ?s)
(handempty ?h2)
(contains ?s ?d1)
(contains ?s ?d2)
(cocktail-part1 ?b ?d1)
(cocktail-part2 ?b ?d2)
(unshaked ?s))
:effect (and (not (unshaked ?s))
(not (contains ?s ?d1))
(not (contains ?s ?d2))
(shaked ?s)
(contains ?s ?b)))

(:action pour-shaker-to-shot
:parameters (?b - beverage ?d - shot ?h - hand ?s - shaker ?l ?l1 - level)
:precondition (and (holding ?h ?s)
(shaked ?s)
(empty ?d)
(clean ?d)
(contains ?s ?b)
(shaker-level ?s ?l)
(next ?l1 ?l))
:effect (and (not (clean ?d))
(not (empty ?d))
(contains ?d ?b)
(shaker-level ?s ?l1)
(not (shaker-level ?s ?l))))
)
7 changes: 7 additions & 0 deletions domains/barman/p01.nl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
You have 1 shaker with 3 levels, 4 shot glasses, 3 dispensers for 3 ingredients.
The shaker and shot glasses are clean, empty, and on the table. Your left and right hands are empty.
The first ingredient of cocktail1 is ingredient1. The second ingredient of cocktail1 is ingredient3.
The first ingredient of cocktail2 is ingredient2. The second ingredient of cocktail2 is ingredient3.
The first ingredient of cocktail3 is ingredient1. The second ingredient of cocktail3 is ingredient2.
Your goal is to make 3 cocktails.
shot1 contains cocktail1. shot2 contains cocktail3. shot3 contains cocktail2.
Loading

0 comments on commit 1853845

Please sign in to comment.