Esempio n. 1
0
def variables_to_numbers(effect, conditions):
    new_effect_args = list(effect.args)
    rename_map = {}
    for i, arg in enumerate(effect.args):
        if arg[0] == "?":
            rename_map[arg] = i
            new_effect_args[i] = i
    new_effect = pddl.Atom(effect.predicate, new_effect_args)

    # There are three possibilities for arguments in conditions:
    # 1. They are variables that occur in the effect. In that case,
    #    they are replaced by the corresponding position in the
    #    effect, as indicated by the rename_map.
    # 2. They are constants. In that case, the unifier must guarantee
    #    that they are matched appropriately. In that case, they are
    #    not modified (remain strings denoting objects).
    # 3. They are variables that don't occur in the effect (are
    #    projected away). This is only allowed in projection rules.
    #    Such arguments are also not modified (remain "?x" strings).

    new_conditions = []
    for cond in conditions:
        new_cond_args = [rename_map.get(arg, arg) for arg in cond.args]
        new_conditions.append(pddl.Atom(cond.predicate, new_cond_args))
    return new_effect, new_conditions
Esempio n. 2
0
def condition_to_rule_body(parameters, condition):
    for par in parameters:
        yield pddl.Atom(par.type, [par.name])
    if not isinstance(condition, pddl.Truth):
        if isinstance(condition, pddl.ExistentialCondition):
            for par in condition.parameters:
                yield pddl.Atom(par.type, [par.name])
            condition = condition.parts[0]
        if isinstance(condition, pddl.Conjunction):
            parts = condition.parts
        else:
            parts = (condition,)
        for part in parts:
            assert isinstance(part, pddl.Literal), "Condition not normalized"
            if not part.negated:
                yield part
Esempio n. 3
0
 def build_rules(self, rules):
     axiom = self.owner
     app_rule_head = get_axiom_predicate(axiom)
     app_rule_body = list(condition_to_rule_body(axiom.parameters, self.condition))
     rules.append((app_rule_body, app_rule_head))
     eff_rule_head = pddl.Atom(axiom.name, [par.name for par in axiom.parameters])
     eff_rule_body = [app_rule_head]
     rules.append((eff_rule_body, eff_rule_head))
Esempio n. 4
0
 def _rename_duplicate_variables(self, atom, new_conditions):
     used_variables = set()
     for i, var_name in enumerate(atom.args):
         if var_name[0] == "?":
             if var_name in used_variables:
                 new_var_name = "%s@%d" % (var_name, len(new_conditions))
                 atom = atom.rename_variables({var_name: new_var_name})
                 new_conditions.append(
                     pddl.Atom("=", [var_name, new_var_name]))
             else:
                 used_variables.add(var_name)
     return atom
Esempio n. 5
0
def substitute_complicated_goal(task):
    goal = task.goal
    if isinstance(goal, pddl.Literal):
        return
    elif isinstance(goal, pddl.Conjunction):
        for item in goal.parts:
            if not isinstance(item, pddl.Literal):
                break
        else:
            return
    new_axiom = task.add_axiom([], goal)
    task.goal = pddl.Atom(new_axiom.name, new_axiom.parameters)
Esempio n. 6
0
    def remove_free_effect_variables(self):
        """Remove free effect variables like the variable Y in the rule
        p(X, Y) :- q(X). This is done by introducing a new predicate
        @object, setting it true for all objects, and translating the above
        rule to p(X, Y) :- q(X), @object(Y).
        After calling this, no new objects should be introduced!"""

        # Note: This should never be necessary for typed domains.
        # Leaving it in at the moment regardless.
        must_add_predicate = False
        for rule in self.rules:
            eff_vars = get_variables([rule.effect])
            cond_vars = get_variables(rule.conditions)
            if not eff_vars.issubset(cond_vars):
                must_add_predicate = True
                eff_vars -= cond_vars
                for var in eff_vars:
                    rule.add_condition(pddl.Atom("@object", [var]))
        if must_add_predicate:
            print("Unbound effect variables: Adding @object predicate.")
            self.facts += [
                Fact(pddl.Atom("@object", [obj])) for obj in self.objects
            ]
Esempio n. 7
0
 def convert_trivial_rules(self):
     """Convert rules with an empty condition into facts.
     This must be called after bounding rule effects, so that rules with an
     empty condition must necessarily have a variable-free effect.
     Variable-free effects are the only ones for which a distinction between
     ground and symbolic atoms is not necessary."""
     must_delete_rules = []
     for i, rule in enumerate(self.rules):
         if not rule.conditions:
             assert not get_variables([rule.effect])
             self.add_fact(
                 pddl.Atom(rule.effect.predicate, rule.effect.args))
             must_delete_rules.append(i)
     if must_delete_rules:
         print("Trivial rules: Converted to facts.")
         for rule_no in must_delete_rules[::-1]:
             del self.rules[rule_no]
Esempio n. 8
0
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()
    prog.dump()
Esempio n. 9
0
def translate_typed_object(prog, obj, type_dict):
    supertypes = type_dict[obj.type].supertype_names
    for type_name in [obj.type] + supertypes:
        prog.add_fact(pddl.Atom(type_name, [obj.name]))
Esempio n. 10
0
 def build_rules(self, rules):
     rule_head_name = "@goal-reachable"
     rule_head = pddl.Atom("@goal-reachable", [])
     rule_body = list(condition_to_rule_body([], self.condition))
     rules.append((rule_body, rule_head))
Esempio n. 11
0
def get_axiom_predicate(axiom):
    name = axiom
    variables = [par.name for par in axiom.parameters]
    if isinstance(axiom.condition, pddl.ExistentialCondition):
        variables += [par.name for par in axiom.condition.parameters]
    return pddl.Atom(name, variables)
Esempio n. 12
0
 def push(self, predicate, args):
     self.num_pushes += 1
     eff_tuple = (predicate, ) + tuple(args)
     if eff_tuple not in self.enqueued:
         self.enqueued.add(eff_tuple)
         self.queue.append(pddl.Atom(predicate, list(args)))
Esempio n. 13
0
def project_rule(rule, conditions, name_generator):
    predicate = name_generator.next()
    effect_variables = set(rule.effect.args) & get_variables(conditions)
    effect = pddl.Atom(predicate, list(effect_variables))
    projected_rule = Rule(conditions, effect)
    return projected_rule
Esempio n. 14
0
 def add_rule(self, type, conditions, effect_vars):
     effect = pddl.Atom(self.name_generator.next(), effect_vars)
     rule = pddl_to_prolog.Rule(conditions, effect)
     rule.type = type
     self.result.append(rule)
     return rule.effect