def add_object(self, obj): assert isinstance(obj, Constant) #assert obj.type in self.type_to_objects self.add_type(obj.type) if obj in self.type_to_objects[obj.type]: return False self.new_problem = True self.name_to_object[obj.name] = obj self.type_to_objects[obj.type].add(obj) if obj in self.object_to_type: raise RuntimeError('Cannot share objects across types: %s vs %s' % (obj.type, self.object_to_type[obj])) assert obj not in self.object_to_type # self.object_to_type[obj] = obj.type if self.use_ground and not isinstance(obj, AbstractConstant): self.add_initial_atom(Concrete(obj)) if self.make_stream_instances and obj.type in self.cond_params: for cs, param in self.cond_params[obj.type]: con_values = [ self.predicate_to_atoms[cond.predicate] for cond in cs.conditions ] param_values = [ self.type_to_objects.get(other.type, []) if param != other else [obj] for other in cs.free_params ] for param_map in parameter_product(cs.conditions, con_values, cs.free_params, param_values): combo = tuple(param_map[p] for p in cs.inputs) if combo not in cs.streams: # Happens when an object is used twice self.add_stream(cs, combo) if self.make_action_instances and obj.type in self.act_params: for act, param in self.act_params[obj.type]: con_values = [ self.predicate_to_atoms[cond.predicate] for cond in self.act_stream_conditions[act] ] param_values = [ self.type_to_objects.get(other.type, []) if param != other else [obj] for other in self.act_free_params[act] ] for param_map in parameter_product( self.act_stream_conditions[act], con_values, self.act_free_params[act], param_values): instance = act.instantiate( tuple(param_map[p] for p in act.parameters)) if instance not in self.action_instances: self.action_instances.add(instance) self.new_instances.append(instance) return True
def add_initial_atom(self, atom): if atom in self.initial_atoms: return False self.new_problem = True self.add_atom(atom) self.initial_atoms.add(atom) if self.is_stream(atom): self.stream_atoms.add(atom) self.predicate_to_atoms[atom.predicate].add(atom) # NOTE - this can be thought of as just the smart instantiate where you limit the values of one thing if self.make_stream_instances and atom.predicate in self.cond_conditions: for cs, con in self.cond_conditions[atom.predicate]: con_values = [ self.predicate_to_atoms[other.predicate] if other != con else [atom] for other in cs.conditions ] param_values = [ self.type_to_objects.get(other.type, []) for other in cs.free_params ] for param_map in parameter_product(cs.conditions, con_values, cs.free_params, param_values): combo = tuple(param_map[p] for p in cs.inputs) if combo not in cs.streams: # Happens when an object is used twice self.add_stream(cs, combo) if self.make_action_instances and atom.predicate in self.act_conditions: for act, con in self.act_conditions[atom.predicate]: con_values = [ self.predicate_to_atoms[other.predicate] if other != con else [atom] for other in self.act_stream_conditions[act] ] param_values = [ self.type_to_objects.get(other.type, []) for other in self.act_free_params[act] ] for param_map in parameter_product( self.act_stream_conditions[act], con_values, self.act_free_params[act], param_values): instance = act.instantiate( tuple(param_map[p] for p in act.parameters)) if instance not in self.action_instances: self.action_instances.add(instance) self.new_instances.append(instance) return True
def state_fluent_bindings(state, action, universe): assert isinstance(action, STRIPSAction) fluents = filter(lambda c: isinstance(c, Atom) and universe.is_fluent(c), action.conditions) initial_atoms = defaultdict(list) for atom in state: initial_atoms[atom.predicate].append(atom) fluent_values = [initial_atoms[f.predicate] for f in fluents] return parameter_product(fluents, fluent_values, [], {})
def get_vertex_keys(vertex, lifted, universe): # TODO - similar to assert isinstance(lifted, STRIPS) and not lifted.neg_conditions( ) # NOTE - only positive conditions for now fluents = filter(universe.is_fluent, lifted.conditions) # TODO - include derived predicates = defaultdict(list) for fluent in vertex.fluents: predicates[fluent.predicate].append(fluent) condition_values = [predicates[c.predicate] for c in fluents] for param_map in parameter_product(fluents, condition_values, [], []): instantiated = tuple( condition.instantiate(param_map) for condition in fluents) yield lifted, instantiated
def recover_bindings(cs, values): predicate_map = defaultdict(list) for eff in values: if isinstance(eff, Atom): predicate_map[eff.predicate].append(eff) effect_values = [predicate_map[eff.predicate] for eff in cs.effects] type_map = defaultdict(list) for obj in values: # TODO - do I want to consider predicate values? if isinstance(obj, Object): type_map[obj.type].append(obj) type_values = [type_map[param.type] for param in cs.free_outputs] for grounding in parameter_product(cs.effects, effect_values, cs.free_outputs, type_values): # TODO - initialize? yield [grounding[param] for param in cs.outputs]
def add_temporary_atom(self, atom): key = get_key(atom) self.add_atom(atom) self.temporary_atoms.add(atom) self.predicate_to_temp_atoms[key].add(atom) for act, con in self.sa_conditions.get(key, []): con_values = [ self.predicate_to_temp_atoms[get_key(other)] if other != con else [atom] for other in act.conditions ] for param_map in parameter_product(act.conditions, con_values, [], {}): instance = act.instantiate( tuple(param_map[p] for p in act.parameters)) if instance not in self.stream_action_instances and instance not in self.temp_blocked and instance not in self.perm_blocked: self.stream_action_instances.add(instance) self.new_stream_actions.append(instance)
def useful_at_state_for_action_old(action, state_fluents, universe): assert isinstance(action, STRIPSAction) fluents = filter(lambda c: isinstance(c, Atom) and universe.is_fluent(c), action.conditions) initial_atoms = defaultdict(list) for f in state_fluents: initial_atoms[f.predicate].append(f) fluent_values = [initial_atoms[f.predicate] for f in fluents] #if any(len(values) == 0 for values in fluent_values): return set(), set() # Comes out implicitly through parameter_product useful_atoms = set() for binding in parameter_product(fluents, fluent_values, [], {}): if not any(isinstance(con, Not) and con.instantiate(binding) in state_fluents for con in action.conditions): # Prunes some negative effects. # TODO - prune more by keeping track of them useful_atoms |= {con.instantiate(binding) for con in action.conditions if universe.is_stream(con)} bound_params = {arg for atom in useful_atoms for arg in atom.args if isinstance(arg, Parameter)} # NOTE - only consider 'free parameters' fluent_params = {a for con in fluents for a in con.args} useful_types = {a.type for a in action.parameters if a not in fluent_params and a not in bound_params} return useful_atoms, useful_types