예제 #1
0
    def recurse(condition):
        existential_parts = []
        other_parts = []
        for part in condition.parts:
            part = recurse(part)
            if isinstance(part, pddl.ExistentialCondition):
                existential_parts.append(part)
            else:
                other_parts.append(part)
        if not existential_parts:
            return condition

        # Rule (1): Combine nested quantifiers.
        if isinstance(condition, pddl.ExistentialCondition):
            new_parameters = condition.parameters + existential_parts[
                0].parameters
            new_parts = existential_parts[0].parts
            return pddl.ExistentialCondition(new_parameters, new_parts)

        # Rule (2): Pull quantifiers out of conjunctions.
        assert isinstance(condition, pddl.Conjunction)
        new_parameters = []
        new_conjunction_parts = other_parts
        for part in existential_parts:
            new_parameters += part.parameters
            new_conjunction_parts += part.parts
        new_conjunction = pddl.Conjunction(new_conjunction_parts)
        return pddl.ExistentialCondition(new_parameters, (new_conjunction, ))
예제 #2
0
def convert_condition(condition):
    import pddl
    class_name = condition.__class__.__name__
    if class_name in ('Truth', 'FunctionComparison'):
        # TODO: currently ignoring numeric conditions
        return pddl.Truth()
    elif class_name == 'Atom':
        return pddl.Atom(condition.predicate, convert_args(condition.args))
    elif class_name == 'NegatedAtom':
        return pddl.NegatedAtom(condition.predicate,
                                convert_args(condition.args))
    elif class_name == 'Conjunction':
        return pddl.conditions.Conjunction(
            list(map(convert_condition, condition.parts)))
    elif class_name == 'Disjunction':
        return pddl.Disjunction(list(map(convert_condition, condition.parts)))
    elif class_name == 'ExistentialCondition':
        return pddl.ExistentialCondition(
            convert_parameters(condition.parameters),
            list(map(convert_condition, condition.parts)))
    elif class_name == 'UniversalCondition':
        return pddl.UniversalCondition(
            convert_parameters(condition.parameters),
            list(map(convert_condition, condition.parts)))
    raise NotImplementedError(class_name)
예제 #3
0
 def recurse(condition, used_variables):
     if isinstance(condition, pddl.Literal):
         typed_vars = []
         conjunction_parts = []
         new_args = []
         for term in condition.args:
             typed, parts, new_term = term.compile_objectfunctions_aux(
                 used_variables)
             typed_vars += typed
             conjunction_parts += parts
             new_args.append(new_term)
         if conjunction_parts == []:
             return condition
         else:
             new_literal = condition.__class__(condition.predicate,
                                               new_args)
             conjunction_parts.append(new_literal)
             conjunction = pddl.Conjunction(conjunction_parts)
             return pddl.ExistentialCondition(typed_vars, [conjunction])
     elif isinstance(condition, pddl.FunctionComparison):
         typed_vars = []
         conjunction_parts = []
         new_parts = []
         for part in condition.parts:
             typed, parts, new_part = part.compile_objectfunctions_aux(
                 used_variables)
             typed_vars += typed
             conjunction_parts += parts
             new_parts.append(new_part)
         if conjunction_parts == []:
             return condition
         else:
             new_comparison = condition.__class__(condition.comparator,
                                                  new_parts)
             conjunction_parts.append(new_comparison)
             conjunction = pddl.Conjunction(conjunction_parts)
             return pddl.ExistentialCondition(typed_vars, [conjunction])
     else:
         new_parts = [
             recurse(part, used_variables) for part in condition.parts
         ]
         return condition.change_parts(new_parts)
예제 #4
0
def parse_condition_aux(alist, negated, type_dict, predicate_dict):
    """Parse a PDDL condition. The condition is translated into NNF on the fly."""
    #    if DEBUG: print ("parsing condition aux %s" % [alist])
    tag = alist[0]
    if is_function_comparison(
            alist
    ):  # NFD conditions are always comparisons between 2 numeric expressions
        args = [parse_expression(arg) for arg in alist[1:]]
        assert len(args) == 2, args
        if negated:
            return pddl.NegatedFunctionComparison(tag, args, True)
        else:
            return pddl.FunctionComparison(tag, args, True)
    elif tag in ("and", "or", "not", "imply"):
        args = alist[1:]
        if tag == "imply":
            assert len(args) == 2
        if tag == "not":
            assert len(args) == 1
            return parse_condition_aux(args[0], not negated, type_dict,
                                       predicate_dict)
    elif tag in ("forall", "exists"):
        parameters = parse_typed_list(alist[1])
        args = alist[2:]
        assert len(args) == 1
    else:
        #         if is_object_comparison(alist):
        #              print("DEBUG: Object comparison!")
        #              print(alist)
        return parse_literal(alist, type_dict, predicate_dict, negated=negated)
    if tag == "imply":
        parts = [
            parse_condition_aux(args[0], not negated, type_dict,
                                predicate_dict),
            parse_condition_aux(args[1], negated, type_dict, predicate_dict)
        ]
        tag = "or"
    else:
        parts = [
            parse_condition_aux(part, negated, type_dict, predicate_dict)
            for part in args
        ]

    if tag == "and" and not negated or tag == "or" and negated:
        return pddl.Conjunction(parts)
    elif tag == "or" and not negated or tag == "and" and negated:
        return pddl.Disjunction(parts)
    elif tag == "forall" and not negated or tag == "exists" and negated:
        return pddl.UniversalCondition(parameters, parts)
    elif tag == "exists" and not negated or tag == "forall" and negated:
        return pddl.ExistentialCondition(parameters, parts)
예제 #5
0
def parse_condition_aux(alist, negated, type_dict, predicate_dict):
    """Parse a PDDL condition. The condition is translated into NNF on the fly."""
    tag = alist[0]
    if tag in ("and", "or", "not", "imply"):
        args = list()
        for arg in alist[1:]:
            if arg[0] == "=":
                continue
            if arg[0] == "not" and arg[1][0] == "=":
                continue
            args.append(arg)
        if tag == "imply":
            assert len(args) == 2
        if tag == "not":
            assert len(args) == 1
            return parse_condition_aux(args[0], not negated, type_dict,
                                       predicate_dict)
    elif tag in ("forall", "exists"):
        parameters = parse_typed_list(alist[1])
        args = alist[2:]
        assert len(args) == 1
    else:
        return parse_literal(alist, type_dict, predicate_dict, negated=negated)

    if tag == "imply":
        parts = [
            parse_condition_aux(args[0], not negated, type_dict,
                                predicate_dict),
            parse_condition_aux(args[1], negated, type_dict, predicate_dict)
        ]
        tag = "or"
    else:
        parts = [
            parse_condition_aux(part, negated, type_dict, predicate_dict)
            for part in args
        ]

    if tag == "and" and not negated or tag == "or" and negated:
        return pddl.Conjunction(parts)
    elif tag == "or" and not negated or tag == "and" and negated:
        return pddl.Disjunction(parts)
    elif tag == "forall" and not negated or tag == "exists" and negated:
        return pddl.UniversalCondition(parameters, parts)
    elif tag == "exists" and not negated or tag == "forall" and negated:
        return pddl.ExistentialCondition(parameters, parts)
예제 #6
0
    def recurse(condition):
        disjunctive_parts = []
        other_parts = []
        for part in condition.parts:
            part = recurse(part)
            if isinstance(part, pddl.Disjunction):
                disjunctive_parts.append(part)
            else:
                other_parts.append(part)
        if not disjunctive_parts:
            return condition

        # Rule (1): Associativity of disjunction.
        if isinstance(condition, pddl.Disjunction):
            result_parts = other_parts
            for part in disjunctive_parts:
                result_parts.extend(part.parts)
            return pddl.Disjunction(result_parts)

        # Rule (2): Distributivity disjunction/existential quantification.
        if isinstance(condition, pddl.ExistentialCondition):
            parameters = condition.parameters
            result_parts = [
                pddl.ExistentialCondition(parameters, (part, ))
                for part in disjunctive_parts[0].parts
            ]
            return pddl.Disjunction(result_parts)

        # Rule (3): Distributivity disjunction/conjunction.
        assert isinstance(condition, pddl.Conjunction)
        result_parts = [pddl.Conjunction(other_parts)]
        while disjunctive_parts:
            previous_result_parts = result_parts
            result_parts = []
            parts_to_distribute = disjunctive_parts.pop().parts
            for part1 in previous_result_parts:
                for part2 in parts_to_distribute:
                    result_parts.append(pddl.Conjunction((part1, part2)))
        return pddl.Disjunction(result_parts)
예제 #7
0
 def recurse(condition, used_variables):
     if isinstance(condition, pddl.Literal):
         typed_vars = []
         conjunction_parts = []
         new_args = []
         for term in condition.args:
             typed, parts, new_term = term.compile_objectfunctions_aux(
                 used_variables)
             typed_vars += typed
             conjunction_parts += parts
             new_args.append(new_term)
         if conjunction_parts == []:
             return condition
         else:
             new_literal = condition.__class__(condition.predicate,
                                               new_args)
             conjunction_parts.append(new_literal)
             conjunction = pddl.Conjunction(conjunction_parts)
             return pddl.ExistentialCondition(typed_vars, [conjunction])
     elif isinstance(condition, pddl.ModuleCall):
         # FIXME no idea what this does, but hopefully the right thing...
         # This is only for object fluents?
         # So probably I don't need this at all and can
         # fallback to default? (return condition?)
         typed_vars = []
         conjunction_parts = []
         new_args = []
         for term in condition.args:
             typed, parts, new_term = term.compile_objectfunctions_aux(
                 used_variables)
             typed_vars += typed
             conjunction_parts += parts
             new_args.append(new_term)
         if conjunction_parts == []:
             return condition
         else:
             new_literal = condition.__class__(condition.name, new_args)
             conjunction_parts.append(new_literal)
             conjunction = pddl.Conjunction(conjunction_parts)
             return pddl.ExistentialCondition(typed_vars, [conjunction])
     elif isinstance(condition, pddl.FunctionComparison):
         typed_vars = []
         conjunction_parts = []
         new_parts = []
         for part in condition.parts:
             typed, parts, new_part = part.compile_objectfunctions_aux(
                 used_variables)
             typed_vars += typed
             conjunction_parts += parts
             new_parts.append(new_part)
         if conjunction_parts == []:
             return condition
         else:
             new_comparison = condition.__class__(condition.comparator,
                                                  new_parts)
             conjunction_parts.append(new_comparison)
             conjunction = pddl.Conjunction(conjunction_parts)
             return pddl.ExistentialCondition(typed_vars, [conjunction])
     else:
         new_parts = [
             recurse(part, used_variables) for part in condition.parts
         ]
         return condition.change_parts(new_parts)