-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' of github.com:AbhijeetKrishnan/expertise-estima…
…tion
- Loading branch information
Showing
37 changed files
with
5,569 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,232 @@ | ||
#!/usr/bin/env python | ||
# Four spaces as indentation [no tabs] | ||
|
||
import re | ||
from action import Action | ||
|
||
class PDDL_Parser: | ||
|
||
SUPPORTED_REQUIREMENTS = [':strips', ':negative-preconditions', ':typing'] | ||
|
||
# ------------------------------------------ | ||
# Tokens | ||
# ------------------------------------------ | ||
|
||
def scan_tokens(self, filename): | ||
with open(filename,'r') as f: | ||
# Remove single line comments | ||
str = re.sub(r';.*$', '', f.read(), flags=re.MULTILINE).lower() | ||
# Tokenize | ||
stack = [] | ||
list = [] | ||
for t in re.findall(r'[()]|[^\s()]+', str): | ||
if t == '(': | ||
stack.append(list) | ||
list = [] | ||
elif t == ')': | ||
if stack: | ||
l = list | ||
list = stack.pop() | ||
list.append(l) | ||
else: | ||
raise Exception('Missing open parentheses') | ||
else: | ||
list.append(t) | ||
if stack: | ||
raise Exception('Missing close parentheses') | ||
if len(list) != 1: | ||
raise Exception('Malformed expression') | ||
return list[0] | ||
|
||
#----------------------------------------------- | ||
# Parse domain | ||
#----------------------------------------------- | ||
|
||
def parse_domain(self, domain_filename): | ||
tokens = self.scan_tokens(domain_filename) | ||
if type(tokens) is list and tokens.pop(0) == 'define': | ||
self.domain_name = 'unknown' | ||
self.requirements = [] | ||
self.types = [] | ||
self.actions = [] | ||
self.predicates = {} | ||
while tokens: | ||
group = tokens.pop(0) | ||
t = group.pop(0) | ||
if t == 'domain': | ||
self.domain_name = group[0] | ||
elif t == ':requirements': | ||
for req in group: | ||
if not req in self.SUPPORTED_REQUIREMENTS: | ||
raise Exception('Requirement ' + req + ' not supported') | ||
self.requirements = group | ||
elif t == ':predicates': | ||
self.parse_predicates(group) | ||
elif t == ':types': | ||
self.types = group | ||
elif t == ':action': | ||
self.parse_action(group) | ||
else: print(str(t) + ' is not recognized in domain') | ||
else: | ||
raise Exception('File ' + domain_filename + ' does not match domain pattern') | ||
|
||
#----------------------------------------------- | ||
# Parse predicates | ||
#----------------------------------------------- | ||
|
||
def parse_predicates(self, group): | ||
for pred in group: | ||
predicate_name = pred.pop(0) | ||
if predicate_name in self.predicates: | ||
raise Exception('Predicate ' + predicate_name + ' redefined') | ||
arguments = {} | ||
untyped_variables = [] | ||
while pred: | ||
t = pred.pop(0) | ||
if t == '-': | ||
if not untyped_variables: | ||
raise Exception('Unexpected hyphen in predicates') | ||
type = pred.pop(0) | ||
while untyped_variables: | ||
arguments[untyped_variables.pop(0)] = type | ||
else: | ||
untyped_variables.append(t) | ||
while untyped_variables: | ||
arguments[untyped_variables.pop(0)] = 'object' | ||
self.predicates[predicate_name] = arguments | ||
|
||
#----------------------------------------------- | ||
# Parse action | ||
#----------------------------------------------- | ||
|
||
def parse_action(self, group): | ||
name = group.pop(0) | ||
if not type(name) is str: | ||
raise Exception('Action without name definition') | ||
for act in self.actions: | ||
if act.name == name: | ||
raise Exception('Action ' + name + ' redefined') | ||
parameters = [] | ||
positive_preconditions = [] | ||
negative_preconditions = [] | ||
add_effects = [] | ||
del_effects = [] | ||
while group: | ||
t = group.pop(0) | ||
if t == ':parameters': | ||
if not type(group) is list: | ||
raise Exception('Error with ' + name + ' parameters') | ||
parameters = [] | ||
untyped_parameters = [] | ||
p = group.pop(0) | ||
while p: | ||
t = p.pop(0) | ||
if t == '-': | ||
if not untyped_parameters: | ||
raise Exception('Unexpected hyphen in ' + name + ' parameters') | ||
ptype = p.pop(0) | ||
while untyped_parameters: | ||
parameters.append([untyped_parameters.pop(0), ptype]) | ||
else: | ||
untyped_parameters.append(t) | ||
while untyped_parameters: | ||
parameters.append([untyped_parameters.pop(0), 'object']) | ||
elif t == ':precondition': | ||
self.split_predicates(group.pop(0), positive_preconditions, negative_preconditions, name, ' preconditions') | ||
elif t == ':effect': | ||
self.split_predicates(group.pop(0), add_effects, del_effects, name, ' effects') | ||
else: print(str(t) + ' is not recognized in action') | ||
self.actions.append(Action(name, parameters, positive_preconditions, negative_preconditions, add_effects, del_effects)) | ||
|
||
#----------------------------------------------- | ||
# Parse problem | ||
#----------------------------------------------- | ||
|
||
def parse_problem(self, problem_filename): | ||
tokens = self.scan_tokens(problem_filename) | ||
if type(tokens) is list and tokens.pop(0) == 'define': | ||
self.problem_name = 'unknown' | ||
self.objects = dict() | ||
self.state = [] | ||
self.positive_goals = [] | ||
self.negative_goals = [] | ||
while tokens: | ||
group = tokens.pop(0) | ||
t = group[0] | ||
if t == 'problem': | ||
self.problem_name = group[-1] | ||
elif t == ':domain': | ||
if self.domain_name != group[-1]: | ||
raise Exception('Different domain specified in problem file') | ||
elif t == ':requirements': | ||
pass # Ignore requirements in problem, parse them in the domain | ||
elif t == ':objects': | ||
group.pop(0) | ||
object_list = [] | ||
while group: | ||
if group[0] == '-': | ||
group.pop(0) | ||
theType = group.pop(0) | ||
if theType in self.objects: | ||
self.objects[theType].extend(object_list) | ||
else: | ||
self.objects[theType] = object_list | ||
object_list = [] | ||
else: | ||
object_list.append(group.pop(0)) | ||
if object_list: | ||
if not 'object' in self.objects: | ||
self.objects['object'] = [] | ||
self.objects['object'] += object_list | ||
elif t == ':init': | ||
group.pop(0) | ||
self.state = group | ||
elif t == ':goal': | ||
self.split_predicates(group[1], self.positive_goals, self.negative_goals, '', 'goals') | ||
else: print(str(t) + ' is not recognized in problem') | ||
else: | ||
raise Exception('File ' + problem_filename + ' does not match problem pattern') | ||
|
||
#----------------------------------------------- | ||
# Split predicates | ||
#----------------------------------------------- | ||
|
||
def split_predicates(self, group, pos, neg, name, part): | ||
if not type(group) is list: | ||
raise Exception('Error with ' + name + part) | ||
if group[0] == 'and': | ||
group.pop(0) | ||
else: | ||
group = [group] | ||
for predicate in group: | ||
if predicate[0] == 'not': | ||
if len(predicate) != 2: | ||
raise Exception('Unexpected not in ' + name + part) | ||
neg.append(predicate[-1]) | ||
else: | ||
pos.append(predicate) | ||
|
||
# ========================================== | ||
# Main | ||
# ========================================== | ||
if __name__ == '__main__': | ||
import sys, pprint | ||
domain = sys.argv[1] | ||
problem = sys.argv[2] | ||
parser = PDDL_Parser() | ||
print('----------------------------') | ||
pprint.pprint(parser.scan_tokens(domain)) | ||
print('----------------------------') | ||
pprint.pprint(parser.scan_tokens(problem)) | ||
print('----------------------------') | ||
parser.parse_domain(domain) | ||
parser.parse_problem(problem) | ||
print('Domain name: ' + parser.domain_name) | ||
for act in parser.actions: | ||
print(act) | ||
print('----------------------------') | ||
print('Problem name: ' + parser.problem_name) | ||
print('Objects: ' + str(parser.objects)) | ||
print('State: ' + str(parser.state)) | ||
print('Positive goals: ' + str(parser.positive_goals)) | ||
print('Negative goals: ' + str(parser.negative_goals)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
|
||
# To reproduce our results, run these commands in your preferred UNIX terminal: | ||
|
||
cd blackout | ||
# Remove the :action-failed lines and whatnot from the trajectory files, so FAMA can use them | ||
cd trajectory | ||
python strip-verbose.py small-verbose.log small-brief.log | ||
python strip-verbose.py medium-verbose.log medium-brief.log | ||
python strip-verbose.py large-verbose.log large-brief.log | ||
cd .. | ||
# Run blackout | ||
python blackout1.py trajectory/small-verbose.log model/small-blackout-1.pddl sokoban-sequential | ||
python blackout2.py trajectory/small-verbose.log model/small-blackout-2.pddl sokoban-sequential | ||
python blackout3.py trajectory/small-verbose.log model/small-blackout-3.pddl sokoban-sequential | ||
python blackout1.py trajectory/medium-verbose.log model/medium-blackout-1.pddl sokoban-sequential | ||
python blackout2.py trajectory/medium-verbose.log model/medium-blackout-2.pddl sokoban-sequential | ||
python blackout3.py trajectory/medium-verbose.log model/medium-blackout-3.pddl sokoban-sequential | ||
python blackout1.py trajectory/large-verbose.log model/large-blackout-1.pddl sokoban-sequential | ||
python blackout2.py trajectory/large-verbose.log model/large-blackout-2.pddl sokoban-sequential | ||
python blackout3.py trajectory/large-verbose.log model/large-blackout-3.pddl sokoban-sequential | ||
# Run FAMA | ||
##TODO insert commands to run FAMA on trajectory/small-brief.log and trajectory/medium-brief.log | ||
## and put the results in model/small-FAMA.pddl and model/medium-FAMA.pddl | ||
## here | ||
# Run evaluation script | ||
cd ../trajectory | ||
python evaluation.py ../blackout/sokoban-sequential.pddl ../blackout/model/small-blackout-1.pddl | ||
python evaluation.py ../blackout/sokoban-sequential.pddl ../blackout/model/small-blackout-2.pddl | ||
python evaluation.py ../blackout/sokoban-sequential.pddl ../blackout/model/small-blackout-3.pddl | ||
python evaluation.py ../blackout/sokoban-sequential.pddl ../blackout/model/small-FAMA.pddl | ||
python evaluation.py ../blackout/sokoban-sequential.pddl ../blackout/model/medium-blackout-1.pddl | ||
python evaluation.py ../blackout/sokoban-sequential.pddl ../blackout/model/medium-blackout-2.pddl | ||
python evaluation.py ../blackout/sokoban-sequential.pddl ../blackout/model/medium-blackout-3.pddl | ||
python evaluation.py ../blackout/sokoban-sequential.pddl ../blackout/model/medium-FAMA.pddl | ||
python evaluation.py ../blackout/sokoban-sequential.pddl ../blackout/model/large-blackout-1.pddl | ||
python evaluation.py ../blackout/sokoban-sequential.pddl ../blackout/model/large-blackout-2.pddl | ||
python evaluation.py ../blackout/sokoban-sequential.pddl ../blackout/model/large-blackout-3.pddl | ||
|
||
|
Oops, something went wrong.