Beispiel #1
0
def instantiate_unsatisfiable(state,
                              action,
                              var_mapping,
                              negative_from_name={}):
    precondition = []
    for effect in action.effects:
        if effect.literal.predicate == UNSATISFIABLE:
            # Condition must be false for plan to succeed
            conditions = set(get_conjunctive_parts(effect.condition))
            negative = {
                literal
                for literal in conditions
                if literal.predicate in negative_from_name
            }
            if not negative:
                continue
            assert len(negative) == 1
            # TODO: handle the case where negative is not used (not (CFree ..))
            normal_conjunction = pddl.Conjunction(conditions - negative)
            # TODO: assumes that can instantiate with just predicate_to_atoms
            normal_effect = pddl.Effect(effect.parameters, normal_conjunction,
                                        effect.literal)
            # TODO: avoid recomputing these
            objects_by_type = instantiate.get_objects_by_type([], [])
            predicate_to_atoms = instantiate.get_atoms_by_predicate(state)
            result = []
            normal_effect.instantiate(var_mapping, state, {effect.literal},
                                      objects_by_type, predicate_to_atoms,
                                      result)
            for _, _, _, mapping in result:
                for literal in negative:
                    new_literal = literal.rename_variables(mapping).negate()
                    assert (not new_literal.free_variables())
                    precondition.append(new_literal)
    return precondition
Beispiel #2
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
Beispiel #3
0
def get_action_instances(task, action_plan):
    type_to_objects = instantiate.get_objects_by_type(task.objects, task.types)
    function_assignments = get_function_assignments(task)
    predicate_to_atoms = instantiate.get_atoms_by_predicate(task.init)
    fluent_facts = MockSet()
    init_facts = set()
    action_instances = []
    for name, objects in action_plan:
        # TODO: what if more than one action of the same name due to normalization?
        # Normalized actions have same effects, so I just have to pick one
        # TODO: conditional effects and internal parameters
        action = find_unique(lambda a: a.name == name, task.actions)
        args = list(map(pddl_from_object, objects))
        variable_mapping = {p.name: a for p, a in safe_zip(action.parameters, args)}
        instance = action.instantiate(variable_mapping, init_facts, fluent_facts, type_to_objects,
                                      task.use_min_cost_metric, function_assignments, predicate_to_atoms)
        assert (instance is not None)
        action_instances.append(instance)
    return action_instances
Beispiel #4
0
def reinstantiate_action(state, instance, negative_from_name={}):
    # Recomputes the instances with without any pruned preconditions
    # TODO: making the assumption that no negative derived predicates
    action = instance.action
    var_mapping = instance.var_mapping
    init_facts = set()
    fluent_facts = MockSet()
    precondition = []
    try:
        action.precondition.instantiate(var_mapping, init_facts, fluent_facts,
                                        precondition)
    except pddl.conditions.Impossible:
        return None
    effects = []
    effect_from_literal = {
        literal: (cond, effect, effect_mapping)
        for cond, literal, effect, effect_mapping in instance.effect_mappings
    }
    for effect in action.effects:
        if effect.literal.predicate == UNSATISFIABLE:
            # Condition must be false for plan to succeed
            conditions = set(get_conjunctive_parts(effect.condition))
            negative = {
                literal
                for literal in conditions
                if literal.predicate in negative_from_name
            }
            if not negative:
                continue
            assert len(negative) == 1
            # TODO: handle the case where negative is not used (not (CFree ..))
            normal_conjunction = pddl.Conjunction(conditions - negative)
            # TODO: assumes that can instantiate with just predicate_to_atoms
            normal_effect = pddl.Effect(effect.parameters, normal_conjunction,
                                        effect.literal)
            # TODO: avoid recomputing these
            objects_by_type = instantiate.get_objects_by_type([], [])
            predicate_to_atoms = instantiate.get_atoms_by_predicate(state)
            result = []
            normal_effect.instantiate(var_mapping, state, {effect.literal},
                                      objects_by_type, predicate_to_atoms,
                                      result)
            for _, _, _, mapping in result:
                for literal in negative:
                    new_literal = literal.rename_variables(mapping).negate()
                    assert (not new_literal.free_variables())
                    precondition.append(new_literal)

    for literal in instance.applied_effects:
        cond, effect, effect_mapping = effect_from_literal[literal]
        if effect is None:  # Stream effect
            #effects.append((cond, literal, cond, effect))
            continue
        else:
            effect._instantiate(effect_mapping, init_facts, fluent_facts,
                                effects)

    new_effects = []
    for cond, effect, e, m in effects:
        precondition.extend(cond)
        new_effects.append(([], effect, e, m))
    return pddl.PropositionalAction(instance.name, precondition, new_effects,
                                    instance.cost, action, var_mapping)