Exemplo n.º 1
0
    def verify_expression(aexp):
        #         print("Verifying ",str(aexp))
        if isinstance(aexp, pddl.PrimitiveNumericExpression):
            #             print("- it is a PNE with fluent",aexp.symbol)
            if not aexp.symbol in function_names:
                msg = (
                    "WARNING: Function symbol '%s' appears in a numeric expression but is not defined in domain file.\n"
                    "Adding new symbol '%s' with arity %d.") % (
                        aexp.symbol, aexp.symbol, len(aexp.args))
                print(msg, file=sys.stderr)
                if len(aexp.args) == 0:
                    newfunction = pddl.Function(aexp.symbol, [], "number")
                    task.functions.append(newfunction)
                    initassignment = pddl.Assign(aexp,
                                                 pddl.NumericConstant(0.0))
                    task.num_init.append(initassignment)
                else:  # if this occurs in an actual domain, maybe we could also determine the type of the parameters of higher-arity functions
                    raise Error(
                        "Don't know the parameters of function %s with arity %d"
                        % (aexp.symbol, len(aexp.args)))
                    assert False


#         elif isinstance(aexp, pddl.NumericConstant):
#             print("- it is a constant: ",aexp.value)
        elif isinstance(aexp, pddl.AdditiveInverse):
            #             print("- it is an additive inverse: ",aexp)
            assert len(parts) == 1
            verify_expression(aexp.parts[0])
        elif isinstance(aexp, pddl.ArithmeticExpression):
            #             print("- it is an arithmetic expression: ",aexp)
            for part in aexp.parts:
                verify_expression(part)
Exemplo n.º 2
0
def parse_function(alist, type_name):
    name = alist[0]
    arguments = parse_typed_list(alist[1:])
    pddl.Task.FUNCTION_SYMBOLS[name] = type_name
    # add function name to function symbol dictionary
    return pddl.Function(name, arguments, type_name)
Exemplo n.º 3
0
def parse_function(alist, type_name):
    name = alist[0]
    arguments = parse_typed_list(alist[1:])
    return pddl.Function(name, arguments, type_name)
Exemplo n.º 4
0
def parse_domain_pddl(domain_pddl):
    def typesplit(
            alist):  # recurse nested lists and replace "-type" by "-", "type"
        # an error which occurs in some sloppyly modeled domains
        ix = 0
        while ix < len(alist):
            el = alist[ix]
            #             print("checking element %s"%el)
            if isinstance(el, list):
                typesplit(alist[ix])
            elif len(el) > 1 and el[0] == "-":
                msg = (
                    "\nWARNING: %s seems to be a 'type' definition missing a space.\n"
                    "Splitting Element into '-' and '%s'") % (el, el[1:])
                print(msg, file=sys.stderr)
                alist[ix:ix + 1] = el[0], el[1:]
            ix += 1

    iterator = iter(domain_pddl)
    define_tag = next(iterator)
    assert define_tag == "define"
    domain_line = next(iterator)
    assert domain_line[0] == "domain" and len(domain_line) == 2
    yield domain_line[1]

    ## We allow an arbitrary order of the requirement, types, constants,
    ## predicates and functions specification. The PDDL BNF is more strict on
    ## this, so we print a warning if it is violated.
    requirements = pddl.Requirements([":strips"])
    the_types = [pddl.Type("object")]
    constants, the_functions = [], []
    the_predicates = [
        pddl.Predicate("=", [
            pddl.TypedObject("?x", "object"),
            pddl.TypedObject("?y", "object")
        ])
    ]
    #    the_free_functions = [] ## support for global constraints with free functions is not implemented yet
    correct_order = [
        ":requirements", ":types", ":constants", ":predicates", ":functions"
    ]  #, ":free_functions"]
    seen_fields = []
    first_action = None
    for opt in iterator:
        #         print("Options before: ",opt)
        typesplit(
            opt)  # fix for missing space between dash '-' and type identifier
        #         print("Options after: ",opt)
        field = opt[0]
        if field not in correct_order:
            first_action = opt
            break
        if field in seen_fields:
            raise SystemExit("Error in domain specification\n" +
                             "Reason: two '%s' specifications." % field)
        if (seen_fields and correct_order.index(seen_fields[-1]) >
                correct_order.index(field)):
            msg = "\nWARNING: %s specification not allowed here (cf. PDDL BNF)" % field
            print(msg, file=sys.stderr)
        seen_fields.append(field)
        if field == ":requirements":
            requirements = pddl.Requirements(opt[1:])
        elif field == ":types":
            the_types.extend(parse_typed_list(opt[1:], constructor=pddl.Type))
        elif field == ":constants":
            constants = parse_typed_list(opt[1:])
        elif field == ":predicates":
            the_predicates += [parse_predicate(entry) for entry in opt[1:]]
        elif field == ":functions":
            the_functions = parse_typed_list(opt[1:],
                                             constructor=parse_function,
                                             default_type="number")


#         elif field == ":free_functions":
#             the_free_functions = parse_typed_list(
#                 opt[1:],
#                 constructor=parse_function,
#                 default_type="number")
    set_supertypes(the_types)
    yield requirements
    yield the_types
    type_dict = dict((pddltype.name, pddltype) for pddltype in the_types)
    yield type_dict
    yield constants
    yield the_predicates
    predicate_dict = dict((pred.name, pred) for pred in the_predicates)
    yield predicate_dict
    total_cost_fluent = pddl.Function("total-cost", [], "number")
    the_functions.append(total_cost_fluent)
    #    the_functions.append(the_free_functions)
    yield the_functions

    entries = []
    if first_action is not None:
        entries.append(first_action)
    entries.extend(iterator)

    the_axioms = []
    the_actions = []
    for entry in entries:
        #         if DEBUG: print("Entries before: ",entry)
        typesplit(
            entry
        )  # fix for missing space between dash '-' and type identifier
        #         if DEBUG: print("Entries after: ",entry)

        if entry[0] == ":derived":
            axiom = parse_axiom(entry, type_dict, predicate_dict)
            the_axioms.append(axiom)
        elif entry[0] == ":action":
            action = parse_action(entry, type_dict, predicate_dict)
            if action is not None:
                the_actions.append(action)
        elif entry[
                0] == ":constraint":  ## support for global constraints is new in NFD
            global_constraint = parse_global_constraint(
                entry, type_dict, predicate_dict)
            the_axioms.append(global_constraint)
        else:
            print("%s could not be parsed" % entry[0])
            if entry[0] != ":free_functions":
                assert False
    yield the_actions
    yield the_axioms