예제 #1
0
def reinstantiate_action_instances(task, old_instances):
    import pddl
    import instantiate
    # Recomputes the instances with without any pruned preconditions
    fluents = get_fluents(task)
    function_assignments = {
        fact.fluent: fact.expression
        for fact in task.init
        if isinstance(fact, pddl.f_expression.FunctionAssignment)
    }
    type_to_objects = instantiate.get_objects_by_type(task.objects, task.types)
    init_facts = set()
    fluent_facts = MockSet()
    new_instances = []
    state = set(task.init)
    for old_instance in old_instances:
        # TODO: better way of instantiating conditional effects (when not fluent)
        #new_instance = reinstantiate_action(old_instance)
        predicate_to_atoms = instantiate.get_atoms_by_predicate({
            a
            for a in state
            if isinstance(a, pddl.Atom) and (a.predicate in fluents)
        })
        action = old_instance.action
        var_mapping = old_instance.var_mapping
        new_instance = action.instantiate(var_mapping, init_facts,
                                          fluent_facts, type_to_objects,
                                          task.use_min_cost_metric,
                                          function_assignments,
                                          predicate_to_atoms)
        assert (new_instance is not None)
        new_instances.append(new_instance)
        apply_action(state, new_instance)
    new_instances.append(get_goal_instance(task.goal))  # TODO: move this?
    return new_instances
예제 #2
0
def compile_to_exogenous_actions(evaluations, domain, streams):
    # TODO: version of this that operates on fluents of length one?
    # TODO: better instantiation when have full parameters
    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)
    future_fn = lambda a: rename_atom(a, future_map)
    new_streams = []
    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
        new_streams.append(create_static_stream(stream, evaluations, fluent_predicates, future_fn))
        stream_atom = new_streams[-1].certified[0]
        add_predicate(domain, make_predicate(get_prefix(stream_atom), get_args(stream_atom)))
        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(make_action(
            name='call-{}'.format(stream.name),
            parameters=get_args(stream_atom),
            preconditions=preconditions,
            effects=stream.certified,
            cost=effort))
        stream.certified = tuple(set(stream.certified) |
                                 set(map(future_fn, stream.certified)))
    if REPLACE_STREAM:
        streams.extend(new_streams)
    else:
        streams[:] = new_streams
예제 #3
0
def reuse_facts(problem, certificate, skeleton):
    # TODO: repackage streams
    # TODO: recover the full axiom + action plan
    # TODO: recover the plan preimage annotated with use time
    # Some supporting args are quantified out and thus lack some facts
    new_facts = []
    if skeleton is None:
        return new_facts
    reuse_objs = set()
    for action, args in skeleton:
        for arg in args:
            if (arg != WILD) and not is_parameter(arg):
                reuse_objs.add(hash_or_id(arg))

    # The reuse relpose omission is due to the fact that the initial pose was selected
    # (which is populated in the initial state)
    order_predicate = ORDER_PREDICATE.format('')
    domain = parse_domain(problem.domain_pddl)
    fluents = get_fluents(domain)
    for fact in certificate.preimage_facts:
        predicate = get_prefix(fact)
        if (predicate in {order_predicate, EQ}) or (predicate in fluents):
            # Could technically evaluate functions as well
            continue
        if all(
                isinstance(arg, str) or (hash_or_id(arg) in reuse_objs)
                for arg in get_args(fact)):
            new_facts.append(fact)
    return new_facts
예제 #4
0
def compile_to_exogenous_axioms(evaluations, domain, streams):
    # TODO: no attribute certified
    # TODO: recover the streams that are required
    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)
    future_fn = lambda a: rename_atom(a, future_map)
    derived_map = {p: 'd-{}'.format(p) for p in certified_predicates}
    derived_fn = lambda a: rename_atom(a, derived_map)
    # TODO: could prune streams that don't need this treatment

    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)
    new_streams = []
    for stream in list(streams):
        if not isinstance(stream, Stream):
            raise NotImplementedError(stream)
        new_streams.append(
            create_static_stream(stream, evaluations, fluent_predicates,
                                 future_fn))
        stream_atom = new_streams[-1].certified[0]
        add_predicate(
            domain,
            make_predicate(get_prefix(stream_atom), get_args(stream_atom)))
        preconditions = [stream_atom] + list(map(derived_fn, stream.domain))
        for certified_fact in stream.certified:
            derived_fact = derived_fn(certified_fact)
            external_params = get_args(derived_fact)
            internal_params = tuple(p for p in (stream.inputs + stream.outputs)
                                    if p not in get_args(derived_fact))
            domain.axioms.extend([
                make_axiom(parameters=external_params,
                           preconditions=[certified_fact],
                           derived=derived_fact),
                make_axiom(parameters=external_params + internal_params,
                           preconditions=preconditions,
                           derived=derived_fact),
            ])
        stream.certified = tuple(
            set(stream.certified) | set(map(future_fn, stream.certified)))
    if REPLACE_STREAM:
        streams.extend(new_streams)
    else:
        streams[:] = new_streams
예제 #5
0
def partition_facts(domain, facts):
    fluents = get_fluents(domain)
    static_facts = []
    fluent_facts = []
    for fact in facts:
        if get_prefix(get_function(fact)).lower() in fluents:
            fluent_facts.append(fact)
        else:
            static_facts.append(fact)
    return static_facts, fluent_facts
예제 #6
0
def instantiate_domain(task, prune_static=True):
    fluent_predicates = get_fluents(task)
    is_static = lambda a: isinstance(a, pddl.Atom) and (a.predicate not in fluent_predicates)

    fluent_facts = MockSet(lambda a: not prune_static or not is_static(a))
    init_facts = set(task.init)
    function_assignments = get_function_assignments(task)
    type_to_objects = instantiate.get_objects_by_type(task.objects, task.types)

    constants_from_predicate = defaultdict(set)
    for action in task.actions + task.axioms:
        for atom in filter(is_static, get_literals(get_precondition(action))):
            constants = tuple((i, a) for i, a in enumerate(atom.args) if not is_parameter(a))
            constants_from_predicate[atom.predicate].add(constants)

    predicate_to_atoms = defaultdict(set)
    args_from_predicate = defaultdict(set)
    for atom in filter(is_static, task.init):  # TODO: compute which predicates might involve constants
        predicate_to_atoms[atom.predicate].add(atom)
        args_from_predicate[atom.predicate].add(atom.args)
        for constants in constants_from_predicate[atom.predicate]:
            if all(atom.args[i] == o for i, o in constants):
                args_from_predicate[atom.predicate, constants].add(atom.args)

    instantiated_actions = []
    for action in task.actions:
        for variable_mapping in instantiate_condition(action, is_static, args_from_predicate):
            inst_action = action.instantiate(variable_mapping, init_facts, fluent_facts, type_to_objects,
                                             task.use_min_cost_metric, function_assignments, predicate_to_atoms)
            if inst_action:
                instantiated_actions.append(inst_action)
    instantiated_axioms = []
    for axiom in task.axioms:
        for variable_mapping in instantiate_condition(axiom, is_static, args_from_predicate):
            inst_axiom = axiom.instantiate(variable_mapping, init_facts, fluent_facts)
            if inst_axiom:
                instantiated_axioms.append(inst_axiom)

    reachable_facts, reachable_operators = get_achieving_axioms(init_facts, instantiated_actions + instantiated_axioms)
    atoms = {atom for atom in (init_facts | set(reachable_facts)) if isinstance(atom, pddl.Atom)}
    relaxed_reachable = all(literal_holds(init_facts, goal) or goal in reachable_facts
                            for goal in instantiate_goal(task.goal))
    reachable_actions = [action for action in reachable_operators
                         if isinstance(action, pddl.PropositionalAction)]
    reachable_axioms = [axiom for axiom in reachable_operators
                        if isinstance(axiom, pddl.PropositionalAxiom)]
    return relaxed_reachable, atoms, reachable_actions, reachable_axioms
예제 #7
0
def apply_actions(domain, state, plan, unit_costs=False):
    # Goal serialization just assumes the tail of the plan includes an abstract action to achieve each condition
    static_state, _ = partition_facts(domain, state)
    print('Static:', static_state)
    # TODO: might need properties that involve an object that aren't useful yet
    evaluations = evaluations_from_init(state)
    #goal_exp = obj_from_value_expression(goal)
    goal_exp = None
    problem = get_problem(evaluations, goal_exp, domain, unit_costs)
    task = task_from_domain_problem(domain, problem)
    task.init = set(task.init)
    for instance in get_action_instances(
            task, transform_plan_args(plan, Object.from_value)):
        apply_action(task.init, instance)
    fluents = get_fluents(domain)
    fluent_state = [
        value_from_evaluation(evaluation_from_fd(atom)) for atom in task.init
        if isinstance(atom, pddl.Atom) and atom.predicate in fluents
    ]
    print('Fluent:', fluent_state)
    state = static_state + fluent_state
    return state
예제 #8
0
def get_exogenous_predicates(domain, streams):
    fluent_predicates = get_fluents(domain)
    domain_predicates = {get_prefix(a) for s in streams for a in s.domain}
    return list(domain_predicates & fluent_predicates)
예제 #9
0
def get_exogenous_predicates(domain, streams):
    return list(get_fluents(domain) & get_domain_predicates(streams))