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)
def get_goal_instance(goal): import pddl #name = '@goal-reachable' name = '@goal' precondition = goal.parts if isinstance(goal, pddl.Conjunction) else [goal] #precondition = get_literals(goal) return pddl.PropositionalAction(name, precondition, [], None)
def extraction_helper(state, instantiated_axioms, goals, negative_from_name={}): # TODO: filter instantiated_axioms that aren't applicable? with Verbose(False): helpful_axioms, axiom_init, _ = axiom_rules.handle_axioms( [], instantiated_axioms, goals) axiom_init = set(axiom_init) axiom_effects = {axiom.effect for axiom in helpful_axioms} #assert len(axiom_effects) == len(axiom_init) for pre in list(goals) + list(axiom_effects): if pre.positive() not in axiom_init: axiom_init.add(pre.positive().negate()) goal_action = pddl.PropositionalAction(GOAL_NAME, goals, [], None) axiom_from_atom, _ = get_achieving_axioms(state | axiom_init, helpful_axioms + [goal_action], negative_from_name) axiom_plan = [] # Could always add all conditions success = extract_axioms(state | axiom_init, axiom_from_atom, goals, axiom_plan, negative_from_name) if not success: print('Warning! Could not extract an axiom plan') #return None return axiom_plan
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
def get_stream_instances(stream_plan): import pddl # TODO: something that inverts the negative items stream_instances = [] # TODO: could even apply these to the state directly for result in stream_plan: name = result.instance.external.name precondition = list(map(fd_from_fact, result.instance.get_domain())) effects = [([], fd_from_fact(fact)) for fact in result.get_certified() if get_prefix(fact) != EQ] cost = None # TODO: effort? instance = pddl.PropositionalAction(name, precondition, effects, cost) stream_instances.append(instance) return stream_instances
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 precondition = list(set(precondition)) + instantiate_unsatisfiable( state, action, var_mapping, negative_from_name) effects = [] effect_from_literal = { literal: (cond, effect, effect_mapping) for cond, literal, effect, effect_mapping in instance.effect_mappings } 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)
def get_goal_instance(goal): return pddl.PropositionalAction(GOAL_NAME, instantiate_goal(goal), [], None)
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)
def compiled_operators(operator): if not COMPILE_AWAY_CONDITIONAL_EFFECTS: yield operator return unconditional_effects = [] conditional_effects = [] simplified_condition = False for e in operator.add_effects: if e[0]: conditional_effects.append(e) else: unconditional_effects.append(e) for cond, atom in operator.del_effects: if atom in cond: # remove deleted atom from effect condition simplified_condition = True cond = [elem for elem in cond if elem != atom] if cond: conditional_effects.append((cond, atom.negate())) else: unconditional_effects.append((cond, atom.negate())) if not conditional_effects: if simplified_condition: yield pddl.PropositionalAction(operator.name, operator.precondition, unconditional_effects, operator.cost) else: yield operator return for i in range(2**(len(conditional_effects))): condition = list(operator.precondition) effects = list(unconditional_effects) exclude_conditions = [] for j, eff in enumerate(conditional_effects): if i >> j & 1: condition.extend(eff[0]) effects.append(([], eff[1])) else: exclude_conditions.append(eff[0]) all_conditions = [condition] for negate in exclude_conditions: if len(negate) == 1: negated = negate[0].negate() for c in all_conditions: c.append(negated) else: new_conds = [] for literal in negate: negated = literal.negate() for cond in all_conditions: new_cond = deepcopy(cond) new_cond.append(negated) new_conds.append(new_cond) all_conditions = new_conds for cond in all_conditions: yield pddl.PropositionalAction(operator.name, cond, effects, operator.cost)
def get_goal_instance(goal): precondition = goal.parts if isinstance(goal, pddl.Conjunction) else [goal] #precondition = get_literals(goal) return pddl.PropositionalAction(GOAL_NAME, precondition, [], None)