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
def __init__(self, task, reachable_action_params, safe=True): self.predicates_to_add_actions = defaultdict(set) self.action_name_to_heavy_action = {} for action in task.durative_actions: if safe: action = self.add_inequality_preconds(action, reachable_action_params) too_heavy_effects = [[], []] create_heavy_act = False for time in xrange(2): for eff in action.effects[time]: if isinstance(eff.peffect, pddl.Atom): predicate = eff.peffect.predicate self.predicates_to_add_actions[predicate].add(action) if safe: too_heavy_effects[time].append(eff) if eff.parameters: # universal effect create_heavy_act = True too_heavy_effects[time].append(eff.copy()) if safe: if create_heavy_act: heavy_act = pddl.DurativeAction( action.name, action.parameters, action.grounding_call, action.duration, action.condition, too_heavy_effects) # heavy_act: duplicated universal effects and assigned unique # names to all quantified variables (implicitly in constructor) self.action_name_to_heavy_action[action.name] = heavy_act else: self.action_name_to_heavy_action[action.name] = action