Beispiel #1
0
def transform_exp_actions(actions, mutex_groups):
    """ 
    Exponential transformation of actions with sdac 
    into actions with constant action costs.
    """

    mutex_dict = dict()
    for group in mutex_groups:
        for elem in group:
            mutex_dict[elem] = group
    del_actions = []
    new_actions = actions
    add_actions = []
    for action in new_actions:
        if isinstance(action.cost, pddl_parser.CostNode):
            del_actions.append(action)
            if not is_usefull(action):
                continue
            at_list = []
            consistent_actions = []
            used_dict = dict()
            for atom in action.cost.get_atoms_set():
                if atom not in mutex_dict:
                    at_list.append(
                        [atom,
                         pddl.NegatedAtom(atom.predicate, atom.args)])
                elif len(mutex_dict[atom]) == 1:
                    at_list.append(
                        [atom,
                         pddl.NegatedAtom(atom.predicate, atom.args)])
                elif str(mutex_dict[atom]) not in used_dict:
                    at_list.append(mutex_dict[atom])
                    used_dict[str(mutex_dict[atom])] = True
            for combi in itertools.product(*at_list):
                pre = []
                pre.extend(action.precondition)
                pre.extend(combi)
                if not is_consistent(combi, action.precondition, mutex_dict):
                    continue
                if isinstance(action, pddl.Action):
                    action_copy = pddl.Action(action.name, action.parameters,
                                              action.num_external_parameters,
                                              pre, action.effects,
                                              str(action.cost.get_cost(combi)))
                else:
                    action_copy = pddl.PropositionalAction(
                        action.name, pre, [], str(action.cost.get_cost(combi)))
                    action_copy.add_effects.extend(action.add_effects)
                    action_copy.del_effects.extend(action.del_effects)
                consistent_actions.append(action_copy)
            add_actions.extend(consistent_actions)
    for a in del_actions:
        new_actions.remove(a)
    new_actions.extend(add_actions)
    return new_actions
Beispiel #2
0
    def add_inequality_preconds(self, action, reachable_action_params):
        if reachable_action_params is None or len(action.parameters) < 2:
            return action
        inequal_params = []
        combs = itertools.combinations(range(len(action.parameters)), 2)
        for pos1, pos2 in combs:
            inequality = True
            for params in reachable_action_params[action.name]:
                if params[pos1] == params[pos2]:
                    inequality = False
                    break
            if inequality:
                inequal_params.append((pos1, pos2))

        if inequal_params:
            precond_parts = list(action.precondition.parts)
            for pos1, pos2 in inequal_params:
                param1 = action.parameters[pos1].name
                param2 = action.parameters[pos2].name
                new_cond = pddl.NegatedAtom("=", (param1, param2))
                precond_parts.append(new_cond)
            precond = action.precondition.change_parts(precond_parts)
            return pddl.Action(action.name, action.parameters, precond,
                               action.effects, action.cost)
        else:
            return action
 def add_inequality_preconds(self, action, reachable_action_params):
     if reachable_action_params is None or len(action.parameters) < 2:
         return action
     new_cond_parts = []
     combs = itertools.combinations(range(len(action.parameters)), 2)
     for pos1, pos2 in combs:
         for params in reachable_action_params[action.name]:
             if params[pos1] == params[pos2]:
                 break
         else:
             param1 = pddl.Variable(action.parameters[pos1].name)
             param2 = pddl.Variable(action.parameters[pos2].name)
             new_cond = pddl.NegatedAtom("=", (param1, param2))
             new_cond_parts.append(new_cond)
     if new_cond_parts:
         new_cond = list(action.condition)
         for time in (0, 2):  # add inequalities to start and end condition
             cond_parts = list(action.condition[time].parts)
             if isinstance(action.condition[time], pddl.Literal):
                 cond_parts = [action.condition[time]]
             cond_parts.extend(new_cond_parts)
             cond = pddl.Conjunction(cond_parts)
             new_cond[time] = cond
         return pddl.DurativeAction(action.name, action.parameters,
                                    action.grounding_call, action.duration,
                                    new_cond, action.effects)
     else:
         return action
Beispiel #4
0
    def add_inequality_preconds(self, action, reachable_action_params):
        if reachable_action_params is None or len(action.parameters) < 2:
            return action
        inequal_params = []
        combs = itertools.combinations(range(len(action.parameters)), 2)
        for pos1, pos2 in combs:
            for params in reachable_action_params[action]:
                if params[pos1] == params[pos2]:
                    break
            else:
                inequal_params.append((pos1, pos2))

        if inequal_params:
            precond_parts = [action.precondition]
            for pos1, pos2 in inequal_params:
                param1 = action.parameters[pos1].name
                param2 = action.parameters[pos2].name
                new_cond = pddl.NegatedAtom("=", (param1, param2))
                precond_parts.append(new_cond)
            precond = pddl.Conjunction(precond_parts).simplified()
            return pddl.Action(
                action.name, action.parameters, action.num_external_parameters,
                precond, action.effects, action.cost)
        else:
            return action
Beispiel #5
0
def convert_condition(condition):
    import pddl
    class_name = condition.__class__.__name__
    if class_name in ('Truth', 'FunctionComparison'):
        # TODO: currently ignoring numeric conditions
        return pddl.Truth()
    elif class_name == 'Atom':
        return pddl.Atom(condition.predicate, convert_args(condition.args))
    elif class_name == 'NegatedAtom':
        return pddl.NegatedAtom(condition.predicate,
                                convert_args(condition.args))
    elif class_name == 'Conjunction':
        return pddl.conditions.Conjunction(
            list(map(convert_condition, condition.parts)))
    elif class_name == 'Disjunction':
        return pddl.Disjunction(list(map(convert_condition, condition.parts)))
    elif class_name == 'ExistentialCondition':
        return pddl.ExistentialCondition(
            convert_parameters(condition.parameters),
            list(map(convert_condition, condition.parts)))
    elif class_name == 'UniversalCondition':
        return pddl.UniversalCondition(
            convert_parameters(condition.parameters),
            list(map(convert_condition, condition.parts)))
    raise NotImplementedError(class_name)
Beispiel #6
0
def add_unsatisfiable_to_goal(domain, goal_expression):
    import pddl
    from pddlstream.language.optimizer import UNSATISFIABLE
    add_predicate(domain, make_predicate(UNSATISFIABLE, []))
    negated_atom = pddl.NegatedAtom(UNSATISFIABLE, tuple())
    for action in domain.actions:
        if negated_atom not in action.precondition.parts:
            action.precondition = pddl.Conjunction(
                [action.precondition, negated_atom]).simplified()
    return And(goal_expression, Not((UNSATISFIABLE, )))
Beispiel #7
0
def fd_from_evaluation(evaluation):
    name = evaluation.head.function
    args = tuple(map(pddl_from_object, evaluation.head.args))
    if is_atom(evaluation):
        return pddl.Atom(name, args)
    elif is_negated_atom(evaluation):
        return pddl.NegatedAtom(name, args)
    fluent = pddl.f_expression.PrimitiveNumericExpression(symbol=name, args=args)
    expression = pddl.f_expression.NumericConstant(evaluation.value)
    return pddl.f_expression.Assign(fluent, expression)
Beispiel #8
0
def add_unsatisfiable_to_goal(domain, goal_expression, negate_actions=False):
    import pddl
    add_predicate(domain, make_predicate(UNSATISFIABLE, []))
    if negate_actions:
        negated_atom = pddl.NegatedAtom(UNSATISFIABLE, tuple())
        for action in domain.actions:
            if negated_atom not in action.precondition.parts:
                action.precondition = pddl.Conjunction(
                    [action.precondition, negated_atom]).simplified()
    return And(goal_expression, Not((UNSATISFIABLE, )))
Beispiel #9
0
def build_evmdd_actions_rek(evm, action_list, action, cost_atoms, aux_dict,
                            mutex_dict, weight, val, first, parent_aux,
                            parent_level, visited):
    aux_string = "evmdd-aux-" + action.name[1:-1].replace(" ", "-") + "-"
    is_first = first
    if str(type(evm)) == "<class 'evmdd.evmdd.Node'>":
        if evm in visited:
            return
        visited[evm] = True
        for i in range(0, len(evm.children)):
            build_evmdd_actions_rek(evm.children[i], action_list, action,
                                    cost_atoms, aux_dict, mutex_dict, weight,
                                    i, is_first, aux_dict[evm], evm.level,
                                    visited)
    elif str(type(evm)) == "<class 'evmdd.evmdd.Edge'>":
        if is_first:
            aux_atom = pddl.Atom(aux_string + aux_dict[evm.succ], [])
            action_copy = pddl.PropositionalAction(action.name[:-1] + "-init-",
                                                   action.precondition, [],
                                                   str(evm.weight))
            action_copy.add_effects.append(([], aux_atom))
            aux_atom_init = pddl.Atom("evmdd-aux-init", [])
            action_copy.add_effects.append(([], aux_atom_init))
            action_copy.precondition.append(aux_atom_init.negate())
            is_first = False
        else:
            if not evm.succ.is_sink_node():
                aux_atom = pddl.Atom(aux_string + aux_dict[evm.succ], [])
            aux_pre_atom = pddl.Atom(aux_string + parent_aux, [])
            pre_atom = cost_atoms[parent_level - 1]
            if val == 0:
                pre_atom = pddl.NegatedAtom(pre_atom.predicate, pre_atom.args)
            pre_copy = []
            pre_copy.append(aux_pre_atom)
            pre_copy.append(pre_atom)
            pre_atom_str = str(pre_atom.predicate)
            for a in pre_atom.args:
                pre_atom_str += "-" + str(a)
            pre_atom_str += "=" + str(val) + "-"
            action_copy = pddl.PropositionalAction(
                action.name[:-1] + "-" + pre_atom_str, pre_copy, [],
                str(evm.weight))
            if evm.succ.is_sink_node():
                action_copy.add_effects.extend(action.add_effects)
                action_copy.del_effects.append(([], aux_pre_atom))
                action_copy.del_effects.extend(action.del_effects)
                aux_atom_init = pddl.Atom("evmdd-aux-init", [])
                action_copy.del_effects.append(([], aux_atom_init))
            else:
                action_copy.add_effects.append(([], aux_atom))
                action_copy.del_effects.append(([], aux_pre_atom))
        action_list.append(action_copy)
        build_evmdd_actions_rek(evm.succ, action_list, action, cost_atoms,
                                aux_dict, mutex_dict, evm.weight, -1, is_first,
                                parent_aux, parent_level, visited)
Beispiel #10
0
def get_action_str(sas_task, task):
    out_str = ""
    if options.evmdd:
        sas_operator_names = []
    else:
        sas_operator_names = [op.name[1:-1] for op in sas_task.operators]
    for pddl_op in task.inst_actions:
        pddl_op_name = pddl_op.name[1:-1]
        if isinstance(pddl_op.cost, str):
            if options.evmdd or pddl_op_name in sas_operator_names:
                out_str += "(:action " + pddl_op_name.replace(
                    " ", "-") + "-" + pddl_op.cost
                out_str += "\n" + ":parameters ()"
                precon_str = "\n:precondition (and "
                eff_list = []
                for atom in pddl_op.precondition:
                    if atom.negated:
                        precon_str += "(not ("
                    else:
                        precon_str += "("
                    precon_str += atom.predicate + " "
                    for arg in atom.args:
                        precon_str += arg + " "
                    if atom.negated:
                        precon_str += "))"
                    else:
                        precon_str += ")"
                for eff in pddl_op.add_effects:
                    eff_list.append(eff[1])
                for eff in pddl_op.del_effects:
                    eff_list.append(
                        pddl.NegatedAtom(eff[1].predicate, eff[1].args))
                out_str += precon_str + ")"
                eff_str = "\n:effect (and "
                for atom in eff_list:
                    if atom.negated:
                        eff_str += "(not ("
                    else:
                        eff_str += "("
                    eff_str += atom.predicate + " "
                    for arg in atom.args:
                        eff_str += arg + " "
                    if atom.negated:
                        eff_str += "))"
                    else:
                        eff_str += ")"
                out_str += eff_str + "(increase (total-cost) " + pddl_op.cost + "))"
                out_str += ")\n"

    return out_str
Beispiel #11
0
def augment_goal(domain, goal_expression, negate_actions=False):
    # TODO: only do this if optimizers are present
    #return goal_expression
    import pddl
    predicate = pddl.predicates.Predicate(UNSATISFIABLE, tuple())
    if predicate.name not in domain.predicate_dict:
        domain.predicates.append(predicate)
        domain.predicate_dict[predicate.name] = predicate
    if negate_actions:
        negated_atom = pddl.NegatedAtom(UNSATISFIABLE, tuple())
        for action in domain.actions:
            if negated_atom not in action.precondition.parts:
                action.precondition = pddl.Conjunction(
                    [action.precondition, negated_atom]).simplified()
    return And(goal_expression, Not((UNSATISFIABLE, )))
Beispiel #12
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)
Beispiel #13
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)
Beispiel #14
0
def create_evmdd_action(action):
    #TODO action parameters?
    name = action.name[1:-1]
    eff_list = []
    #TODO conditional effects?
    for eff in action.add_effects:
        eff_list.append(eff[1])
    for eff in action.del_effects:
        eff_list.append(pddl.NegatedAtom(eff[1].predicate, eff[1].args))
    prec_facts = []
    eff_facts = []
    for prec in action.precondition:
        prec_facts.append(atom_to_mdd_fact(prec))
    for eff in eff_list:
        eff_facts.append(atom_to_mdd_fact(eff))
    return Action(name, prec_facts, eff_facts, get_cost_function(action.cost))
Beispiel #15
0
def parse_literal(alist, type_dict, predicate_dict, negated=False):
    if alist[0] == "not":
        assert len(alist) == 2
        alist = alist[1]
        negated = not negated

    pred_id, arity = _get_predicate_id_and_arity(alist[0], type_dict,
                                                 predicate_dict)

    if arity != len(alist) - 1:
        raise SystemExit("predicate used with wrong arity: (%s)" %
                         " ".join(alist))

    if negated:
        return pddl.NegatedAtom(pred_id, alist[1:])
    else:
        return pddl.Atom(pred_id, alist[1:])
Beispiel #16
0
def get_init(init_evaluations, negated=False):
    # TODO: this doesn't include =
    init = []
    for evaluation in init_evaluations:
        name = evaluation.head.function
        args = tuple(map(pddl_from_object, evaluation.head.args))
        if is_atom(evaluation):
            init.append(pddl.Atom(name, args))
        elif negated and is_negated_atom(evaluation):
            init.append(pddl.NegatedAtom(name, args))
        else:
            fluent = pddl.f_expression.PrimitiveNumericExpression(symbol=name,
                                                                  args=args)
            expression = pddl.f_expression.NumericConstant(
                evaluation.value)  # Integer
            init.append(pddl.f_expression.Assign(fluent, expression))
    return init
Beispiel #17
0
 def lit_replacement(condition, obj_map):
     if isinstance(condition, pddl.Literal):
         if isinstance(condition, pddl.Atom):
             return pddl.Atom(
                 condition.predicate,
                 [obj_map.get(arg, arg) for arg in condition.args])
         elif isinstance(condition, pddl.NegatedAtom):
             return pddl.NegatedAtom(
                 condition.predicate,
                 [obj_map.get(arg, arg) for arg in condition.args])
         else:
             assert False, "What is a Literal but not an atom??"
     else:
         new_parts = [
             lit_replacement(part, obj_map) for part in condition.parts
         ]
         return condition.change_parts(new_parts)
     return True
def parse_state(new_state, all_literals):
    state = []
    state_true = set()
    state_false = set()
    state_assignments = dict()
    for fact in new_state:
        if fact[0] == "=":
            try:
                assignment = parse_assignment(fact)
            except ValueError as e:
                raise SystemExit("Error in initial state specification\n" +
                                 "Reason: %s." % e)
            if not isinstance(assignment.expression,
                              pddl.NumericConstant):
                raise SystemExit("Illegal assignment in initial state " +
                                 "specification:\n%s" % assignment)
            if assignment.fluent in state_assignments:
                prev = state_assignments[assignment.fluent]
                if assignment.expression == prev.expression:
                    print("Warning: %s is specified twice" % assignment,
                          "in initial state specification")
                else:
                    raise SystemExit("Error in initial state specification\n" +
                                     "Reason: conflicting assignment for " +
                                     "%s." % assignment.fluent)
            else:
                state_assignments[assignment.fluent] = assignment
                state.append(assignment)
        elif fact[0] == "not":
            atom = pddl.Atom(fact[1][0], fact[1][1:])
            check_atom_consistency(atom, state_false, state_true, False)
            state_false.add(atom)
        else:
            atom = pddl.Atom(fact[0], fact[1:])
            check_atom_consistency(atom, state_true, state_false)
            state_true.add(atom)
    state.extend(state_true)
    for atom in all_literals.difference(state_true):
        state.append(pddl.NegatedAtom(atom.predicate, atom.args))
    return sorted(state)