Esempio n. 1
0
 def replace(condition):
     if isinstance(condition, pddl.FunctionComparison):
         non_negated = condition
         if condition.negated:
             non_negated = condition.negate()
         # remove possible duplicates
         fluent_str = 'num_condition_satisfied{0}'.format(task.comparator_count)
         new_predicate_args = dict()
         functions = condition.get_functions()
         for func in functions:
             arg_types = extract_arg_types(func)
             for (key, value) in zip(func.args, arg_types):
                 new_predicate_args[key] = pddl.TypedObject(key, value)
         args = []
         for key in sorted(new_predicate_args.keys()):
             args.append(new_predicate_args[key])
         predicate = pddl.Predicate(fluent_str, args)
         task.predicates.append(predicate)
         if condition.negated:
             new_atom = pddl.NegatedNumericWrapper(predicate.name, [x.name for x in args], non_negated)
         else:
             new_atom = pddl.NumericWrapper(predicate.name, [x.name for x in args], non_negated)
         task.comparator_count += 1
         return new_atom
     if condition.has_numeric_precondition():
         new_condition = condition.__class__([])
         new_condition.parts = [replace(x) for x in condition.parts]
         return new_condition
     return condition
Esempio n. 2
0
def add_stream_actions(domain, stream_results, **kwargs):
    import pddl
    stream_actions, stream_result_from_name = get_stream_actions(
        stream_results, **kwargs)
    output_objects = []
    for stream_result in stream_result_from_name.values():
        if isinstance(stream_result, StreamResult):
            output_objects.extend(
                map(pddl_from_object, stream_result.output_objects))
    new_constants = list(
        {pddl.TypedObject(obj, OBJECT)
         for obj in output_objects} | set(domain.constants))
    # to_untyped_strips
    # free_variables
    new_domain = Domain(domain.name, domain.requirements, domain.types,
                        domain.type_dict, new_constants, domain.predicates,
                        domain.predicate_dict, domain.functions,
                        domain.actions[:] + stream_actions, domain.axioms)
    """
    optimizer_results = list(filter(is_optimizer_result, stream_results))
    optimizer_facts = {substitute_expression(result.external.stream_fact, result.get_mapping())
                       for result in optimizer_results}
    optimizers = {result.external.optimizer for result in optimizer_results}
    print(optimizers)
    for optimizer in optimizers:
        for stream in optimizer.streams:
            print(stream.instance.get_constraints())
            print(stream.instance)
    #print(optimizer_results)
    #print(optimizer_facts)
    """
    return new_domain, stream_result_from_name
Esempio n. 3
0
def compile_to_exogenous_axioms(evaluations, domain, streams):
    # TODO: no attribute certified
    import pddl
    fluent_predicates = get_fluents(domain)
    certified_predicates = {
        get_prefix(a)
        for s in streams for a in s.certified
    }
    future_map = {p: 'f-{}'.format(p) for p in certified_predicates}
    augment_evaluations(evaluations, future_map)
    rename_future = lambda a: rename_atom(a, future_map)
    derived_map = {p: 'd-{}'.format(p) for p in certified_predicates}
    rename_derived = lambda a: rename_atom(a, derived_map)

    for action in domain.actions:
        action.precondition = replace_predicates(derived_map,
                                                 action.precondition)
        for effect in action.effects:
            assert (isinstance(effect, pddl.Effect))
            effect.condition = replace_predicates(derived_map,
                                                  effect.condition)
    for axiom in domain.axioms:
        axiom.condition = replace_predicates(derived_map, axiom.condition)

    #fluent_predicates.update(certified_predicates)
    for stream in list(streams):
        if not isinstance(stream, Stream):
            raise NotImplementedError(stream)
        streams.append(
            create_static_stream(stream, evaluations, fluent_predicates,
                                 rename_future))
        stream_atom = streams[-1].certified[0]
        domain.predicate_dict[get_prefix(stream_atom)] = pddl.Predicate(
            get_prefix(stream_atom), get_args(stream_atom))
        preconditions = [stream_atom] + list(map(rename_derived,
                                                 stream.domain))
        for fact in stream.certified:
            derived_fact = fd_from_fact(rename_derived(fact))
            external_params = derived_fact.args
            internal_params = tuple(p for p in (stream.inputs + stream.outputs)
                                    if p not in derived_fact.args)
            parameters = tuple(
                pddl.TypedObject(p, OBJECT)
                for p in (external_params + internal_params))
            #precondition = pddl.Conjunction(tuple(map(fd_from_fact, [stream_atom] +
            #                                        list(map(rename_derived, stream.domain)))))
            #precondition = pddl.Disjunction([fd_from_fact(fact), precondition]) # TODO: quantifier
            domain.axioms.extend([
                pddl.Axiom(name=derived_fact.predicate,
                           parameters=parameters,
                           num_external_parameters=len(external_params),
                           condition=make_preconditions(preconditions)),
                pddl.Axiom(name=derived_fact.predicate,
                           parameters=parameters[:len(external_params)],
                           num_external_parameters=len(external_params),
                           condition=fd_from_fact(fact)),
            ])
        stream.certified = tuple(
            set(stream.certified) | set(map(rename_future, stream.certified)))
Esempio n. 4
0
def get_problem(init_evaluations, goal_expression, domain, unit_costs=False):
    objects = objects_from_evaluations(init_evaluations)
    typed_objects = list({pddl.TypedObject(pddl_from_object(obj), OBJECT) for obj in objects} - set(domain.constants))
    # TODO: this doesn't include =
    init = [fd_from_evaluation(e) for e in init_evaluations if not is_negated_atom(e)]
    goal = parse_goal(goal_expression, domain)
    return Problem(task_name=domain.name, task_domain_name=domain.name, objects=sorted(typed_objects, key=lambda o: o.name),
                   task_requirements=pddl.tasks.Requirements([]), init=init, goal=goal, use_metric=not unit_costs)
Esempio n. 5
0
def parse_domain_custom(checker):
    # parse domain file
    checker.parse_code(checker.files['domain'], checker.parse_token_domain)

    yield checker.names['domain']
    if checker.requirements:
        yield pddl.Requirements(checker.requirements)
    else:
        yield pddl.Requirements([":strips"])

    types = [pddl.Type("object")]
    set_supertypes(types)
    type_dict = dict((type_.name, type_) for type_ in types)
    yield types
    yield type_dict
    yield []

    predicates = [[pred] + checker.predicates[pred]['params']
                  for pred in checker.predicates]
    predicates = [parse_predicate(entry) for entry in predicates]
    predicates += [
        pddl.Predicate("=", [
            pddl.TypedObject("?x", "object"),
            pddl.TypedObject("?y", "object")
        ])
    ]
    predicate_dict = dict((pred.name, pred) for pred in predicates)
    yield predicates
    yield predicate_dict
    yield []

    actions = []
    entries = [[
        ':action', action, ':parameters', checker.actions[action]['params'],
        ':precondition', checker.actions[action]['logic_precs'], ':effect',
        checker.actions[action]['logic_effs']
    ] for action in checker.actions]
    for entry in entries:
        action = parse_action(entry, type_dict, predicate_dict)
        if action is not None:
            actions.append(action)
    yield actions
    yield []
Esempio n. 6
0
def get_problem(evaluations, goal_exp, domain, unit_costs=False):
    objects = objects_from_evaluations(evaluations)
    typed_objects = list({pddl.TypedObject(pddl_from_object(obj), OBJECT) for obj in objects} - set(domain.constants))
    # TODO: this doesn't include =
    init = [fd_from_evaluation(e) for e in evaluations if not is_negated_atom(e)]
    goal = pddl.Truth() if goal_exp is None else parse_goal(goal_exp, domain)
    problem_pddl = None
    if USE_FORBID:
        problem_pddl = get_problem_pddl(evaluations, goal_exp, domain.pddl, temporal=False)
    write_pddl(domain.pddl, problem_pddl)
    return Problem(task_name=domain.name, task_domain_name=domain.name,
                   objects=sorted(typed_objects, key=lambda o: o.name),
                   task_requirements=pddl.tasks.Requirements([]), init=init, goal=goal,
                   use_metric=not unit_costs, pddl=problem_pddl)
Esempio n. 7
0
def get_problem(init_evaluations, goal_expression, domain, unit_costs):
    objects = map(pddl_from_object, objects_from_evaluations(init_evaluations))
    typed_objects = list({pddl.TypedObject(obj, OBJECT)
                          for obj in objects} - set(domain.constants))
    init = get_init(init_evaluations)
    goal = parse_condition(pddl_list_from_expression(goal_expression),
                           domain.type_dict, domain.predicate_dict)
    return Problem(task_name=domain.name,
                   task_domain_name=domain.name,
                   objects=typed_objects,
                   task_requirements=pddl.tasks.Requirements([]),
                   init=init,
                   goal=goal,
                   use_metric=not unit_costs)
Esempio n. 8
0
 def recurse(condition):
     # Uses new_axioms_by_condition and type_map from surrounding scope.
     if isinstance(condition, pddl.UniversalCondition):
         axiom_condition = condition.negate()
         parameters = sorted(axiom_condition.free_variables())
         typed_parameters = tuple(pddl.TypedObject(v, type_map[v]) for v in parameters)
         axiom = new_axioms_by_condition.get((axiom_condition, typed_parameters))
         if not axiom:
             condition = recurse(axiom_condition)
             axiom = task.add_axiom(list(typed_parameters), condition)
             new_axioms_by_condition[(condition, typed_parameters)] = axiom
         return pddl.NegatedAtom(axiom.name, parameters)
     else:
         new_parts = [recurse(part) for part in condition.parts]
         return condition.change_parts(new_parts)
Esempio n. 9
0
 def recurse(condition):
   # Uses new_axioms_by_condition and type_map from surrounding scope.
   if isinstance(condition, pddl.UniversalCondition):
     axiom_condition = condition.negate()
     parameters = axiom_condition.free_variables()
     axiom = new_axioms_by_condition.get(axiom_condition)
     if not axiom:
       typed_parameters = [pddl.TypedObject(v, type_map[v]) for v in parameters]
       condition = recurse(axiom_condition)
       axiom = task.add_axiom(typed_parameters, condition)
       new_axioms_by_condition[condition] = axiom
     return pddl.NegatedAtom(axiom.name, [pddl.conditions.parse_term(par) for par in parameters])
   else:
     new_parts = [recurse(part) for part in condition.parts]
     return condition.change_parts(new_parts)
Esempio n. 10
0
def add_stream_actions(domain, stream_results):
    import pddl
    stream_actions, stream_result_from_name = get_stream_actions(stream_results)
    output_objects = []
    for stream_result in stream_result_from_name.values():
        if isinstance(stream_result, StreamResult):
            output_objects += list(map(pddl_from_object, stream_result.output_objects))
    new_constants = list({pddl.TypedObject(obj, OBJECT) for obj in output_objects} | set(domain.constants))
    # to_untyped_strips
    # free_variables
    new_domain = Domain(domain.name, domain.requirements, domain.types, domain.type_dict,
                        new_constants,
                        domain.predicates, domain.predicate_dict, domain.functions,
                        domain.actions[:] + stream_actions, domain.axioms)
    return new_domain, stream_result_from_name
Esempio n. 11
0
 def get_atom_parameter(self, alist, predicate_dict, parameters_dict,
                        parent):
     """
     Initiate Atoms of a cost-term
     """
     par = None
     pre_arg = 0
     args = []
     alist_save = list(alist)
     try:
         pre = predicate_dict[alist[0]]
     except:
         if (alist[0] not in parent.unbound_check):
             raise ValueError(alist[0], " is not a predicate or parameter")
     alist = alist[1:]
     for index in range(0, len(alist)):
         par = parameters_dict.get(alist[index])
         for un_par in parent.unbound_check:
             parl = un_par.split(" - ")
             assert (len(parl) <= 2)
             par_str1 = parl[0]
             par_str2 = "object"
             if len(parl) > 1:
                 par_str2 = parl[1]
             if alist[index] == par_str1:
                 par = pddl.TypedObject(par_str1, par_str2)
                 break
         if not par:
             par = alist[index]
         if not isinstance(
                 par,
                 str) and par.type_name != pre.arguments[index].type_name:
             raise ValueError("Predicate", pre.name,
                              "must have argument of type",
                              pre.arguments[index].type_name, "at index",
                              index, ". Got", par.type_name)
         pre_arg += 1
         if isinstance(par, str):
             args.append(par)
         else:
             args.append(par.name)
     if pre_arg != pre.get_arity():
         raise ValueError(
             "Number of arguments of predicate", pre.name,
             "does not match the number of arguments in costfunction")
     return pddl.Atom(pre.name, args)
Esempio n. 12
0
def compile_to_exogenous_actions(evaluations, domain, streams):
    import pddl
    # TODO: automatically derive fluents
    # TODO: version of this that operates on fluents of length one?
    # TODO: better instantiation when have full parameters
    # TODO: conversion from stream cost to real cost units?
    # TODO: any predicates derived would need to be replaced as well
    fluent_predicates = get_fluents(domain)
    certified_predicates = {
        get_prefix(a)
        for s in streams for a in s.certified
    }
    future_map = {p: 'f-{}'.format(p) for p in certified_predicates}
    augment_evaluations(evaluations, future_map)
    rename_future = lambda a: rename_atom(a, future_map)
    for stream in list(streams):
        if not isinstance(stream, Stream):
            raise NotImplementedError(stream)
        # TODO: could also just have conditions asserting that one of the fluent conditions fails
        streams.append(
            create_static_stream(stream, evaluations, fluent_predicates,
                                 rename_future))
        stream_atom = streams[-1].certified[0]
        parameters = [
            pddl.TypedObject(p, OBJECT) for p in get_args(stream_atom)
        ]
        # TODO: add to predicates as well?
        domain.predicate_dict[get_prefix(stream_atom)] = pddl.Predicate(
            get_prefix(stream_atom), parameters)
        preconditions = [stream_atom] + list(stream.domain)
        effort = 1  # TODO: use stream info
        #effort = 1 if unit_cost else result.instance.get_effort()
        #if effort == INF:
        #    continue
        domain.actions.append(
            pddl.Action(name='call-{}'.format(stream.name),
                        parameters=parameters,
                        num_external_parameters=len(parameters),
                        precondition=make_preconditions(preconditions),
                        effects=make_effects(stream.certified),
                        cost=make_cost(effort)))
        stream.certified = tuple(
            set(stream.certified) | set(map(rename_future, stream.certified)))
Esempio n. 13
0
def compile_to_exogenous_actions(evaluations, domain, streams):
    import pddl
    # TODO: automatically derive fluents
    # TODO: version of this that operates on fluents of length one?
    # TODO: better instantiation when have full parameters
    # TODO: conversion from stream cost to real cost units?
    # TODO: any predicates derived would need to be replaced as well
    fluent_predicates = get_fluents(domain)
    domain_predicates = {get_prefix(a) for s in streams for a in s.domain}
    if not (domain_predicates & fluent_predicates):
        return

    certified_predicates = {get_prefix(a) for s in streams for a in s.certified}
    future_map = {p: 'f-{}'.format(p) for p in certified_predicates}
    augment_evaluations(evaluations, future_map)
    rename_future = lambda a: rename_atom(a, future_map)
    for stream in list(streams):
        if not isinstance(stream, Stream):
            raise NotImplementedError(stream)
        # TODO: could also just have conditions asserting that one of the fluent conditions fails
        streams.append(create_static_stream(stream, evaluations, fluent_predicates, rename_future))
        stream_atom = streams[-1].certified[0]
        parameters = [pddl.TypedObject(p, 'object') for p in get_args(stream_atom)]
        # TODO: add to predicates as well?
        domain.predicate_dict[get_prefix(stream_atom)] = pddl.Predicate(get_prefix(stream_atom), parameters)
        precondition = pddl.Conjunction(tuple(map(fd_from_fact, (stream_atom,) + tuple(stream.domain))))
        effects = [pddl.Effect(parameters=[], condition=pddl.Truth(),
                               literal=fd_from_fact(fact)) for fact in stream.certified]
        effort = 1 # TODO: use stream info
        #effort = 1 if unit_cost else result.instance.get_effort()
        #if effort == INF:
        #    continue
        fluent = pddl.PrimitiveNumericExpression(symbol=TOTAL_COST, args=[])
        expression = pddl.NumericConstant(int_ceil(effort)) # Integer
        cost = pddl.Increase(fluent=fluent, expression=expression) # Can also be None
        domain.actions.append(pddl.Action(name='call-{}'.format(stream.name),
                                          parameters=parameters,
                                          num_external_parameters=len(parameters),
                                          precondition=precondition, effects=effects, cost=cost))
        stream.certified = tuple(set(stream.certified) |
                                 set(map(rename_future, stream.certified)))
Esempio n. 14
0
def parse_domain_pddl(domain_pddl):
    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_predicates, the_functions = [], [], []
    correct_order = [
        ":requirements", ":types", ":constants", ":predicates", ":functions"
    ]
    seen_fields = []
    for opt in iterator:
        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:]]
            the_predicates += [
                pddl.Predicate("=", [
                    pddl.TypedObject("?x", "object"),
                    pddl.TypedObject("?y", "object")
                ])
            ]
        elif field == ":functions":
            the_functions = parse_typed_list(opt[1:],
                                             constructor=parse_function,
                                             default_type="number")
    set_supertypes(the_types)
    yield requirements
    yield the_types
    type_dict = dict((type.name, type) for type 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
    yield the_functions

    entries = [first_action] + [entry for entry in iterator]
    the_axioms = []
    the_actions = []
    for entry in entries:
        if entry[0] == ":derived":
            axiom = parse_axiom(entry, type_dict, predicate_dict)
            the_axioms.append(axiom)
        else:
            action = parse_action(entry, type_dict, predicate_dict)
            if action is not None:
                the_actions.append(action)
    yield the_actions
    yield the_axioms
def translate_typed_object(prog, obj, type_dict):
    supertypes = type_dict[obj.type_name].supertype_names
    for type_name in [obj.type_name] + supertypes:
        prog.add_fact(pddl.TypedObject(obj.name, type_name).get_atom())
Esempio n. 16
0
def make_object(obj, type=OBJECT):
    return pddl.TypedObject(obj, type)
Esempio n. 17
0
def convert_parameters(parameters):
    import pddl
    return [pddl.TypedObject(param.name, param.type) for param in parameters]
Esempio n. 18
0
def make_parameters(parameters):
    return tuple(pddl.TypedObject(p, OBJECT) for p in parameters)
Esempio n. 19
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