def split_rule(rule, name_generator): important_conditions, trivial_conditions = [], [] for cond in rule.conditions: for arg in cond.args: if arg[0] == "?": important_conditions.append(cond) break else: trivial_conditions.append(cond) # important_conditions = [cond for cond in rule.conditions if cond.args] # trivial_conditions = [cond for cond in rule.conditions if not cond.args] components = get_connected_conditions(important_conditions) if len(components) == 1 and not trivial_conditions: return split_into_binary_rules(rule, name_generator) projected_rules = [ project_rule(rule, conditions, name_generator) for conditions in components ] result = [] for proj_rule in projected_rules: result += split_into_binary_rules(proj_rule, name_generator) conditions = ([proj_rule.effect for proj_rule in projected_rules] + trivial_conditions) combining_rule = Rule(conditions, rule.effect) if len(conditions) >= 2: combining_rule.type = "product" else: combining_rule.type = "project" result.append(combining_rule) return result
def split_rule(rule, name_generator): important_conditions, trivial_conditions = [], [] for cond in rule.conditions: for arg in cond.args: if arg[0] == "?": important_conditions.append(cond) break else: trivial_conditions.append(cond) # important_conditions = [cond for cond in rule.conditions if cond.args] # trivial_conditions = [cond for cond in rule.conditions if not cond.args] components = get_connected_conditions(important_conditions) if len(components) == 1 and not trivial_conditions: return split_into_binary_rules(rule, name_generator) projected_rules = [project_rule(rule, conditions, name_generator) for conditions in components] result = [] for proj_rule in projected_rules: result += split_into_binary_rules(proj_rule, name_generator) conditions = [proj_rule.effect for proj_rule in projected_rules] + \ trivial_conditions combining_rule = Rule(conditions, rule.effect) if len(conditions) >= 2: combining_rule.type = "product" else: combining_rule.type = "project" result.append(combining_rule) return result
def split_rule(rule, name_generator): # Capture original rule weight weight = rule.weight important_conditions, trivial_conditions = [], [] for cond in rule.conditions: for arg in cond.args: if arg[0] == "?": important_conditions.append(cond) break else: trivial_conditions.append(cond) # important_conditions = [cond for cond in rule.conditions if cond.args] # trivial_conditions = [cond for cond in rule.conditions if not cond.args] components = get_connected_conditions(important_conditions) if len(components) == 1 and not trivial_conditions: return split_into_binary_rules(rule, name_generator) projected_rules = [ project_rule(rule, conditions, name_generator) for conditions in components ] result = [] for proj_rule in projected_rules: result += split_into_binary_rules(proj_rule, name_generator) conditions = ([proj_rule.effect for proj_rule in projected_rules] + trivial_conditions) combining_rule = Rule(conditions, rule.effect) if len(conditions) >= 2: combining_rule.type = "product" else: combining_rule.type = "project" result.append(combining_rule) # Last rule is always the "root" rule. It weight should be updated # TODO Make this more reliable result[-1].weight = weight return result
def test_normalization(): prog = PrologProgram() prog.add_fact(pddl.Atom("at", ["foo", "bar"])) prog.add_fact(pddl.Atom("truck", ["bollerwagen"])) prog.add_fact(pddl.Atom("truck", ["segway"])) prog.add_rule(Rule([pddl.Atom("truck", ["?X"])], pddl.Atom("at", ["?X", "?Y"]))) prog.add_rule(Rule([pddl.Atom("truck", ["X"]), pddl.Atom("location", ["?Y"])], pddl.Atom("at", ["?X", "?Y"]))) prog.add_rule(Rule([pddl.Atom("truck", ["?X"]), pddl.Atom("location", ["?Y"])], pddl.Atom("at", ["?X", "?X"]))) prog.add_rule(Rule([pddl.Atom("p", ["?Y", "?Z", "?Y", "?Z"])], pddl.Atom("q", ["?Y", "?Y"]))) prog.add_rule(Rule([], pddl.Atom("foo", []))) prog.add_rule(Rule([], pddl.Atom("bar", ["X"]))) prog.normalize() output = StringIO() prog.dump(file=output) sorted_output = "\n".join(sorted(output.getvalue().splitlines())) assert sorted_output == """\
def project_rule(rule, conditions, name_generator): predicate = next(name_generator) effect_variables = set(rule.effect.args) & get_variables(conditions) effect = pddl.Atom(predicate, sorted(effect_variables)) projected_rule = Rule(conditions, effect) return projected_rule