예제 #1
0
def instantiate_condition(action, is_static, args_from_predicate):
    parameters = {p.name for p in action.parameters}
    #if not parameters:
    #    yield {}
    #    return
    static_conditions = list(
        filter(is_static, get_literals(get_precondition(action))))
    static_parameters = set(
        filter(is_parameter, flatten(atom.args for atom in static_conditions)))
    if not (parameters <= static_parameters):
        raise NotImplementedError(
            'Could not instantiate action {} due to parameters: {}'.format(
                action.name, str_from_object(parameters - static_parameters)))
    atoms_from_cond = {
        condition: args_from_predicate[condition.predicate,
                                       get_constants(condition)]
        for condition in static_conditions
    }
    conditions, atoms = zip(*atoms_from_cond.items())
    relations = [
        Relation(conditions[index].args, atoms[index])
        for index in compute_order(conditions, atoms)
    ]
    solution = solve_satisfaction(relations)
    for element in solution.body:
        yield solution.get_mapping(element)
예제 #2
0
def recover_axioms_plans(instantiated, action_instances):
    #axioms, axiom_init, _ = axiom_rules.handle_axioms(
    #    instantiated.actions, instantiated.axioms, instantiated.goal_list)

    new_action_instances = [
        copy.deepcopy(instance) for instance in action_instances
    ]

    axioms, axiom_init = instantiated.axioms, [
    ]  # TODO: bug when needing to reachieve negated
    axioms_from_effect = defaultdict(list)
    for axiom in axioms:
        axioms_from_effect[axiom.effect].append(axiom)
    axioms_from_name = get_derived_predicates(instantiated.task.axioms)

    state = set(instantiated.task.init) | set(axiom_init)
    axiom_plans = []
    for action in new_action_instances + [
            get_goal_instance(instantiated.task.goal)
    ]:
        all_conditions = list(get_precondition(action)) + list(
            flatten(cond
                    for cond, _ in action.add_effects + action.del_effects))
        axioms = backtrack_axioms(all_conditions, axioms_from_effect, set())
        axiom_from_atom, _ = get_achieving_axioms(state, axioms)

        action.applied_effects = []
        for effects in [action.add_effects, action.del_effects]:
            negate = (effects is action.del_effects)
            for i, (conditions, effect) in reversed(list(enumerate(effects))):
                if all(
                        literal_holds(state, literal) or (
                            literal in axiom_from_atom)
                        for literal in conditions):
                    action.precondition.extend(conditions)
                    effects[i] = ([], effect)
                    action.applied_effects.append(
                        effect.negate() if negate else effect)
                else:
                    effects.pop(i)

        # RuntimeError: Preimage fact ('new-axiom@0',) is not achievable!
        #precondition = action.precondition # TODO: strange bug if this applies
        precondition = [
            literal for literal in action.precondition
            if literal.predicate in axioms_from_name
        ]
        axiom_plans.append([])
        success = extract_axioms(state, axiom_from_atom, precondition,
                                 axiom_plans[-1])
        if not success:
            print(all_conditions)
            print(action)
            print(axioms)
            raise RuntimeError('Could not extract axioms')
        apply_action(state, action)
    return new_action_instances, axiom_plans
예제 #3
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
예제 #4
0
def get_achieving_axioms(state, operators, negated_from_name={}):
    # TODO: order by stream effort
    # marking algorithm for propositional Horn logic
    unprocessed_from_literal = defaultdict(list)
    operator_from_literal = {}
    remaining_from_stream = {}
    reachable_operators = set()  # TODO: only keep facts

    queue = deque()

    def process_axiom(op, effect):
        reachable_operators.add(id(op))
        if effect not in operator_from_literal:
            operator_from_literal[effect] = op
            queue.append(effect)

    # TODO: could produce a list of all derived conditions
    for op in operators:
        preconditions = get_precondition(op)
        for cond, effect in get_conditional_effects(op):
            conditions = cond + preconditions
            remaining_from_stream[id(op), effect] = 0
            for literal in filter_negated(conditions, negated_from_name):
                if literal_holds(state, literal):
                    operator_from_literal[literal] = None
                else:
                    remaining_from_stream[id(op), effect] += 1
                    unprocessed_from_literal[literal].append((op, effect))
            if remaining_from_stream[id(op), effect] == 0:
                process_axiom(op, effect)

    while queue:
        literal = queue.popleft()
        for op, effect in unprocessed_from_literal[literal]:
            remaining_from_stream[id(op), effect] -= 1
            if remaining_from_stream[id(op), effect] == 0:
                process_axiom(op, effect)
    return operator_from_literal, [
        op for op in operators if id(op) in reachable_operators
    ]
예제 #5
0
def recover_axioms_plans(instantiated, action_instances):
    #axioms, axiom_init, _ = axiom_rules.handle_axioms(
    #    instantiated.actions, instantiated.axioms, instantiated.goal_list)
    axioms, axiom_init = instantiated.axioms, [
    ]  # TODO: bug when needing to reachieve negated
    axioms_from_effect = defaultdict(list)
    for axiom in axioms:
        axioms_from_effect[axiom.effect].append(axiom)

    state = set(instantiated.task.init) | set(axiom_init)
    axiom_plans = []
    for action in action_instances + [
            get_goal_instance(instantiated.task.goal)
    ]:
        all_conditions = list(get_precondition(action)) + list(
            flatten(cond
                    for cond, _ in action.add_effects + action.del_effects))
        axioms = backtrack_axioms(all_conditions, axioms_from_effect, set())
        axiom_from_atom, _ = get_achieving_axioms(state, axioms)
        action.applied_effects = []
        for effects in [action.add_effects, action.del_effects]:
            negate = effects is action.del_effects
            for i, (conditions, effect) in reversed(list(enumerate(effects))):
                if all(
                        literal_holds(state, literal) or (
                            literal in axiom_from_atom)
                        for literal in conditions):
                    action.precondition.extend(conditions)
                    effects[i] = ([], effect)
                    action.applied_effects.append(
                        effect.negate() if negate else effect)
                else:
                    effects.pop(i)
        axiom_plans.append([])
        assert extract_axioms(state, axiom_from_atom, action.precondition,
                              axiom_plans[-1])
        apply_action(state, action)
    return axiom_plans