Ejemplo n.º 1
0
def negate(axioms):
    assert axioms
    result = [
        pddl.PropositionalAxiom(axioms[0].name, [], axioms[0].effect.negate())
    ]
    for axiom in axioms:
        condition = axiom.condition
        if len(condition) == 0:
            # The derived fact we want to negate is triggered with an
            # empty condition, so it is always true and its negation
            # is always false.
            return []
        elif len(condition) == 1:  # Handle easy special case quickly.
            new_literal = condition[0].negate()
            for result_axiom in result:
                result_axiom.condition.append(new_literal)
        else:
            new_result = []
            for literal in condition:
                literal = literal.negate()
                for result_axiom in result:
                    new_axiom = result_axiom.clone()
                    new_axiom.condition.append(literal)
                    new_result.append(new_axiom)
            result = new_result
    result = simplify(result)
    return result
Ejemplo n.º 2
0
def compute_negative_axioms(clusters):
    for cluster in clusters:
        if cluster.needed_negatively:
            if len(cluster.variables) > 1:
                # If the cluster contains multiple variables, they have a cyclic
                # positive dependency. In this case, the "obvious" way of
                # negating the formula defining the derived variable is
                # semantically wrong. For details, see issue453.
                #
                # Therefore, in this case we perform a naive overapproximation
                # instead, which assumes that derived variables occurring in
                # such clusters can be false unconditionally. This is good
                # enough for correctness of the code that uses these negated
                # axioms (within heuristics of the search component), but loses
                # accuracy. Negating the rules in an exact
                # (non-overapproximating) way is possible but more expensive.
                # Again, see issue453 for details.
                for variable in cluster.variables:
                    axioms = cluster.axioms[variable]
                    negated_axiom = pddl.PropositionalAxiom(
                        axioms[0].name, [], variable.negate(), axioms[0].axiom,
                        axioms[0].var_mapping)
                    cluster.axioms[variable].append(negated_axiom)
            else:
                variable = next(iter(cluster.variables))
                negated_axioms = negate(cluster.axioms[variable])
                cluster.axioms[variable] += negated_axioms
Ejemplo n.º 3
0
def add_optimizer_axioms(results, instantiated):
    # Ends up being a little slower than version in optimizer.py when not blocking shared
    # TODO: add this to simultaneous
    import pddl
    results_from_instance = defaultdict(list)
    for result in results:
        results_from_instance[result.instance].append(result)
    optimizer_results = list(filter(is_optimizer_result, results))
    optimizers = {result.external.optimizer for result in optimizer_results}
    for optimizer in optimizers:
        optimizer_facts = {
            substitute_expression(result.external.stream_fact,
                                  result.get_mapping())
            for result in optimizer_results
            if result.external.optimizer is optimizer
        }
        facts_from_arg = defaultdict(list)
        for fact in optimizer_facts:
            for arg in get_args(fact):
                facts_from_arg[arg].append(fact)

        for stream in optimizer.streams:
            if not stream.instance.disabled:
                continue
            constraints = stream.instance.get_constraints()
            output_variables = []
            for out in stream.output_objects:
                assert isinstance(out.param, UniqueOptValue)
                output_variables.append([
                    r.output_objects[out.param.output_index]
                    for r in results_from_instance[out.param.instance]
                ])
            for combo in product(*output_variables):
                mapping = get_mapping(stream.output_objects, combo)
                name = '({})'.join(UNSATISFIABLE)
                blocked = set(substitute_expression(constraints, mapping))
                additional = {
                    fact
                    for arg in combo for fact in facts_from_arg[arg]
                } - blocked
                # TODO: like a partial disable, if something has no outputs, then adding things isn't going to help
                if stream.instance.enumerated and not stream.instance.successes:
                    # Assumes the optimizer is submodular
                    condition = list(map(fd_from_fact, blocked))
                else:
                    condition = list(
                        map(fd_from_fact, blocked | set(map(Not, additional))))
                effect = fd_from_fact((UNSATISFIABLE, ))
                instantiated.axioms.append(
                    pddl.PropositionalAxiom(name, condition, effect))
                instantiated.atoms.add(effect)
Ejemplo n.º 4
0
def negate(axioms):
    assert axioms
    result = [pddl.PropositionalAxiom(axioms[0].name, [], axioms[0].effect.negate())]
    for axiom in axioms:
        condition = axiom.condition
        length_cond = len(condition)
        assert length_cond > 0, "Negated axiom impossible; cannot deal with that"
        if length_cond == 1: # Handle easy special case quickly.
            new_literal = condition[0].negate()
            for result_axiom in result:
                result_axiom.condition.append(new_literal)
        elif length_cond == 2:
            new_literal1 = condition[0].negate()
            new_literal2 = condition[1].negate()
            new_result = []
            for result_axiom in result:
                new_axiom = result_axiom.clone()
                new_axiom.condition.append(new_literal1)
                new_result.append(new_axiom)
                result_axiom.condition.append(new_literal2)
            result.extend(new_result)
        else:
            new_result = []
            for i in range(1, len(condition)):
                literal = condition[i].negate()
                for result_axiom in result:
                    new_axiom = result_axiom.clone()
                    new_axiom.condition.append(literal)
                    new_result.append(new_axiom)
            for result_axiom in result:
                result_axiom.append(literal)
            result.extend(new_result)
        #else:
        #    new_result = []
        #    for literal in condition:
        #        literal = literal.negate()
        #        for result_axiom in result:
        #            new_axiom = result_axiom.clone()
        #            new_axiom.condition.append(literal)
        #            new_result.append(new_axiom)
        #    result = new_result
    result = simplify(result)
    return result
Ejemplo n.º 5
0
def negate(axioms):
    assert axioms
    result = [pddl.PropositionalAxiom(axioms[0].name, [], axioms[0].effect.negate())]
    for axiom in axioms:
        condition = axiom.condition
        assert len(condition) > 0, "Negated axiom impossible; cannot deal with that"
        if len(condition) == 1:  # Handle easy special case quickly.
            new_literal = condition[0].negate()
            for result_axiom in result:
                result_axiom.condition.append(new_literal)
        else:
            new_result = []
            for literal in condition:
                literal = literal.negate()
                for result_axiom in result:
                    new_axiom = result_axiom.clone()
                    new_axiom.condition.append(literal)
                    new_result.append(new_axiom)
            result = new_result
    result = simplify(result)
    return result
Ejemplo n.º 6
0
def compute_groups(task, atoms, reachable_action_params,actions,axioms):

    print(options.invariant)
    if options.invariant == 'mip':
        groups = mip_invariant_finder.get_groups(task,reachable_action_params,atoms,actions)
    else:
        groups = invariant_finder.get_groups(task, reachable_action_params)
        
        with timers.timing("Instantiating groups"):
            groups = instantiate_groups(groups, task, atoms)
#         groups = [group for group in groups if is_group_useful(group,atoms)]

    # Sort here already to get deterministic mutex groups.
    groups = sort_groups(groups)
    # TODO: I think that collect_all_mutex_groups should do the same thing
    #       as choose_groups with partial_encoding=False, so these two should
    #       be unified.
    with timers.timing("Collecting mutex groups"):
        mutex_groups = collect_all_mutex_groups(groups, atoms)

    inessentials = defaultdict(list)
    if options.group_choice == 'exact':
        with timers.timing("Choosing groups", block=True):
            essentials = mip.choose_groups_exact(groups, atoms)
    elif options.group_choice == 'essential':
        with timers.timing("Computing exactly groups", block=True):
            exactly1 = exactly_groups.compute_groups(task,actions,mutex_groups)
        with timers.timing("Choosing groups", block=True):
            essentials,inessentials = mip.choose_groups_essential_exact(mutex_groups,exactly1,atoms)
    else:
        with timers.timing("Choosing groups", block=True):
            essentials = choose_groups(groups, atoms)
    groups = essentials + [[item] for item in inessentials.keys()]

    if options.group_choice == 'essential' and options.axiom:
        task.init = [item for item in task.init if  not isinstance(item,pddl.Assign) and not item in inessentials ]
        actions = [action.filt(inessentials) for action in actions]
        for k,v in inessentials.items():
            if len(v) <= 1:
                axiom = pddl.PropositionalAxiom(k,[],k)
                axioms.append(axiom)
                continue
            neg = pddl.Atom("neg-" + k.predicate,k.args)
            groups.append([neg])
            atoms.add(neg)
            for atom in v:
                neg_axiom = pddl.PropositionalAxiom(neg,[atom],neg)
                axiom = pddl.PropositionalAxiom(k,[neg.negate()],k)
                axioms.append(neg_axiom)
                axioms.append(axiom)

    groups = sort_groups(groups)
#     for item in groups:
#         print(item)
    with timers.timing("Building translation key"):
        translation_key = build_translation_key(groups)

    if DEBUG:
        for group in groups:
            if len(group) >= 2:
                print("{%s}" % ", ".join(map(str, group)))
    return groups, mutex_groups, translation_key,(inessentials)