Go to the documentation of this file.00001
00002
00003
00004
00005 import copy
00006
00007 from pddl_to_prolog import Rule, get_variables
00008 import graph
00009 import greedy_join
00010 import pddl
00011
00012 def get_connected_conditions(conditions):
00013 agraph = graph.Graph(conditions)
00014 var_to_conditions = dict([(var, [])
00015 for var in get_variables(conditions)])
00016 for cond in conditions:
00017 for var in cond.args:
00018 if isinstance(var,pddl.Variable):
00019 var_to_conditions[var].append(cond)
00020
00021
00022 for var, conds in var_to_conditions.iteritems():
00023 for cond in conds[1:]:
00024 agraph.connect(conds[0], cond)
00025 return agraph.connected_components()
00026
00027 def project_rule(rule, conditions, name_generator):
00028 predicate = name_generator.next()
00029 effect_variables = set(rule.effect.args) & get_variables(conditions)
00030 effect = pddl.Atom(predicate, list(effect_variables))
00031 projected_rule = Rule(conditions, effect)
00032 return projected_rule
00033
00034 def split_rule(rule, name_generator):
00035 important_conditions, trivial_conditions = [], []
00036 for cond in rule.conditions:
00037 for term in cond.args:
00038 if isinstance(term,pddl.Variable):
00039 important_conditions.append(cond)
00040 break
00041 else:
00042 trivial_conditions.append(cond)
00043
00044
00045
00046
00047 components = get_connected_conditions(important_conditions)
00048 if len(components) == 1 and not trivial_conditions:
00049 return split_into_binary_rules(rule, name_generator)
00050
00051 projected_rules = [project_rule(rule, conditions, name_generator)
00052 for conditions in components]
00053 result = []
00054 for proj_rule in projected_rules:
00055 result += split_into_binary_rules(proj_rule, name_generator)
00056
00057 conditions = [proj_rule.effect for proj_rule in projected_rules] + \
00058 trivial_conditions
00059 combining_rule = Rule(conditions, rule.effect)
00060 if len(conditions) >= 2:
00061 combining_rule.type = "product"
00062 else:
00063 combining_rule.type = "project"
00064 result.append(combining_rule)
00065 return result
00066
00067 def split_into_binary_rules(rule, name_generator):
00068 if len(rule.conditions) <= 1:
00069 rule.type = "project"
00070 return [rule]
00071 return greedy_join.greedy_join(rule, name_generator)