def parse_objects(board, types): to_ret = set() to_ret.add(TypedEntity(PLAYER, types['thing'])) for o in [DIR_DOWN, DIR_LEFT, DIR_RIGHT, DIR_UP]: to_ret.add(TypedEntity(o, types['direction'])) for i, _ in enumerate(board.boxes): to_ret.add(TypedEntity("stone-{}".format(i), types['thing'])) for p in board.movables: to_ret.add(TypedEntity("pos-{}-{}".format(p.x, p.y), types['location'])) for p in board.walls: to_ret.add(TypedEntity("pos-{}-{}".format(p.x, p.y), types['location'])) return sorted(to_ret)
def _parse_objects(self, objects): if objects.find("\n") != -1: objects = objects.split("\n") elif self.uses_typing: # Must be one object then; assumes that typed objects are new-line separated assert objects.count(" - ") == 1 objects = [objects] else: # Space-separated objects = objects.split() to_return = set() for obj in objects: if self.uses_typing: obj_name, obj_type_name = obj.strip().split(" - ") obj_name = obj_name.strip() obj_type_name = obj_type_name.strip() else: obj_name = obj.strip() if " - " in obj_name: obj_name, temp = obj_name.split(" - ") obj_name = obj_name.strip() assert temp == "default" obj_type_name = "default" if obj_type_name not in self.types: print( "Warning: type not declared for object {}, type {}".format( obj_name, obj_type_name)) obj_type = Type(obj_type_name) else: obj_type = self.types[obj_type_name] to_return.add(TypedEntity(obj_name, obj_type)) return sorted(to_return)
def parse_goal(board, types, predicates): all_preds = [ predicates["at-goal"]( *[TypedEntity("stone-{}".format(i), types['thing'])]) for i, _ in enumerate(board.boxes) ] return LiteralConjunction(all_preds)
def parse_objects(objects, types, uses_typing=False): if uses_typing: split_objects = [] remaining_str = objects while True: try: obj, remaining_str = re.split(r"\s-\s|\n-\s", remaining_str, 1) except ValueError: break if " " in remaining_str: object_type, remaining_str = re.split( r"[\s]+|[\n]+", remaining_str, 1) else: object_type = remaining_str remaining_str = "" split_objects.append(obj + " - " + object_type) objects = split_objects else: objects = objects.split() obj_names = [] obj_type_names = [] for obj in objects: if uses_typing: obj_name, obj_type_name = obj.strip().split(" - ") obj_name = obj_name.strip() obj_type_name = obj_type_name.strip() if len(obj_name.split()) > 1: for single_obj_name in obj_name.split(): obj_names.append(single_obj_name.strip()) obj_type_names.append(obj_type_name) else: obj_names.append(obj_name) obj_type_names.append(obj_type_name) else: obj_name = obj.strip() if " - " in obj_name: obj_name, temp = obj_name.split(" - ") obj_name = obj_name.strip() assert temp == "default" obj_type_name = "default" obj_names.append(obj_name) obj_type_names.append(obj_type_name) to_return = set() for obj_name, obj_type_name in zip(obj_names, obj_type_names): if obj_type_name not in types: print( "Warning: type not declared for object {}, type {}".format( obj_name, obj_type_name)) obj_type = Type(obj_type_name) else: obj_type = types[obj_type_name] to_return.add(TypedEntity(obj_name, obj_type)) return sorted(to_return)
def _parse_objects(self, objects): if self.uses_typing: # Assume typed objects are new-line separated. objects = objects.split("\n") else: # Untyped objects can be separated by any form of whitespace. objects = objects.split() obj_names = [] obj_type_names = [] for obj in objects: if self.uses_typing: obj_name, obj_type_name = obj.strip().split(" - ") obj_name = obj_name.strip() obj_type_name = obj_type_name.strip() if len(obj_name.split()) > 1: for single_obj_name in obj_name.split(): obj_names.append(single_obj_name.strip()) obj_type_names.append(obj_type_name) else: obj_names.append(obj_name) obj_type_names.append(obj_type_name) else: obj_name = obj.strip() if " - " in obj_name: obj_name, temp = obj_name.split(" - ") obj_name = obj_name.strip() assert temp == "default" obj_type_name = "default" obj_names.append(obj_name) obj_type_names.append(obj_type_name) to_return = set() for obj_name, obj_type_name in zip(obj_names, obj_type_names): if obj_type_name not in self.types: print( "Warning: type not declared for object {}, type {}".format( obj_name, obj_type_name)) obj_type = Type(obj_type_name) else: obj_type = self.types[obj_type_name] to_return.add(TypedEntity(obj_name, obj_type)) return sorted(to_return)
def _parse_into_literal(self, string, params, is_effect=False): """Parse the given string (representing either preconditions or effects) into a literal. Check against params to make sure typing is correct. """ assert string[0] == "(" assert string[-1] == ")" if string.startswith("(and") and string[4] in (" ", "\n", "("): clauses = self._find_all_balanced_expressions(string[4:-1].strip()) return LiteralConjunction([ self._parse_into_literal(clause, params, is_effect=is_effect) for clause in clauses ]) if string.startswith("(or") and string[3] in (" ", "\n", "("): clauses = self._find_all_balanced_expressions(string[3:-1].strip()) return LiteralDisjunction([ self._parse_into_literal(clause, params, is_effect=is_effect) for clause in clauses ]) if string.startswith("(forall") and string[7] in (" ", "\n", "("): new_binding, clause = self._find_all_balanced_expressions( string[7:-1].strip()) new_name, new_type_name = new_binding.strip()[1:-1].split("-") new_name = new_name.strip() new_type_name = new_type_name.strip() assert new_name not in params, "ForAll variable {} already exists".format( new_name) params[new_name] = self.types[new_type_name] result = ForAll( self._parse_into_literal(clause, params, is_effect=is_effect), TypedEntity(new_name, params[new_name])) del params[new_name] return result if string.startswith("(exists") and string[7] in (" ", "\n", "("): new_binding, clause = self._find_all_balanced_expressions( string[7:-1].strip()) if new_binding[1:-1] == "": # Handle existential goal with no arguments. body = self._parse_into_literal(clause, params, is_effect=is_effect) return body variables = self._parse_objects(new_binding[1:-1]) for v in variables: params[v.name] = v.var_type body = self._parse_into_literal(clause, params, is_effect=is_effect) result = Exists(variables, body) for v in variables: del params[v.name] return result if string.startswith("(probabilistic") and string[14] in (" ", "\n", "("): assert is_effect, "We only support probabilistic effects" lits = [] probs = [] expr = string[14:-1].strip() for match in re.finditer("(\d*\.?\d+)", expr): prob = float(match.group()) subexpr = self._find_balanced_expression( expr[match.end():].strip(), 0) lit = self._parse_into_literal(subexpr, params, is_effect=is_effect) lits.append(lit) probs.append(prob) return ProbabilisticEffect(lits, probs) if string.startswith("(not") and string[4] in (" ", "\n", "("): clause = string[4:-1].strip() if is_effect: return Anti( self._parse_into_literal(clause, params, is_effect=is_effect)) else: return Not( self._parse_into_literal(clause, params, is_effect=is_effect)) string = string[1:-1].split() pred, args = string[0], string[1:] typed_args = [] # Validate types against the given params dict. assert pred in self.predicates, "Predicate {} is not defined".format( pred) assert self.predicates[pred].arity == len(args), pred for i, arg in enumerate(args): if arg not in params: raise Exception("Argument {} not in params {}".format( arg, params)) assert arg in params, "Argument {} is not in the params".format( arg) if isinstance(params, dict): typed_arg = TypedEntity(arg, params[arg]) else: typed_arg = params[params.index(arg)] typed_args.append(typed_arg) return self.predicates[pred](*typed_args)
def _parse_into_literal(self, string, params, is_effect=False): """Parse the given string (representing either preconditions or effects) into a literal. Check against params to make sure typing is correct. """ assert string[0] == "(" assert string[-1] == ")" if string.startswith("(and") and string[4] in (" ", "\n", "("): clauses = self._find_all_balanced_expressions(string[4:-1].strip()) return LiteralConjunction([ self._parse_into_literal(clause, params, is_effect=is_effect) for clause in clauses ]) if string.startswith("(or") and string[3] in (" ", "\n", "("): clauses = self._find_all_balanced_expressions(string[3:-1].strip()) return LiteralDisjunction([ self._parse_into_literal(clause, params, is_effect=is_effect) for clause in clauses ]) if string.startswith("(forall") and string[7] in (" ", "\n", "("): new_binding, clause = self._find_all_balanced_expressions( string[7:-1].strip()) new_name, new_type_name = new_binding.strip()[1:-1].split("-") new_name = new_name.strip() new_type_name = new_type_name.strip() assert new_name not in params, "ForAll variable {} already exists".format( new_name) params[new_name] = self.types[new_type_name] result = ForAll( self._parse_into_literal(clause, params, is_effect=is_effect), TypedEntity(new_name, params[new_name])) del params[new_name] return result if string.startswith("(exists") and string[7] in (" ", "\n", "("): new_binding, clause = self._find_all_balanced_expressions( string[7:-1].strip()) variables = self._parse_objects(new_binding[1:-1]) for v in variables: params[v.name] = v.var_type body = self._parse_into_literal(clause, params, is_effect=is_effect) result = Exists(variables, body) for v in variables: del params[v.name] return result if string.startswith("(not") and string[4] in (" ", "\n", "("): clause = string[4:-1].strip() if is_effect: return Anti( self._parse_into_literal(clause, params, is_effect=is_effect)) else: return Not( self._parse_into_literal(clause, params, is_effect=is_effect)) string = string[1:-1].split() pred, args = string[0], string[1:] # Validate types against the given params dict. assert pred in self.predicates, "Predicate {} is not defined".format( pred) assert self.predicates[pred].arity == len(args), pred for i, arg in enumerate(args): if arg not in params: import ipdb ipdb.set_trace() assert arg in params, "Argument {} is not in the params".format( arg) return self.predicates[pred](*args)
def parse_initial_state(board, types, predicates): initial_lits = set() for dir in [DIR_RIGHT, DIR_LEFT, DIR_DOWN, DIR_UP]: initial_lits.add(predicates['move'](*[ TypedEntity(dir, types['direction']), ])) initial_lits.add(predicates['at'](*[ TypedEntity(PLAYER, types['thing']), TypedEntity("pos-{}-{}".format(board.player.x, board.player.y), types['location']) ])) initial_lits.add(predicates['is-player'](*[ TypedEntity(PLAYER, types['thing']), ])) for i, box in enumerate(board.boxes): if box in board.goals: initial_lits.add(predicates['at-goal']( *[TypedEntity("stone-{}".format(i), types['thing'])])) initial_lits.add(predicates['at'](*[ TypedEntity("stone-{}".format(i), types['thing']), TypedEntity("pos-{}-{}".format(box.x, box.y), types['location']) ])) initial_lits.add(predicates['is-stone'](*[ TypedEntity("stone-{}".format(i), types['thing']), ])) for spot in board.walls: initial_lits.add(predicates['is-nongoal'](*[ TypedEntity("pos-{}-{}".format(spot.x, spot.y), types['location']), ])) for spot in board.movables: if spot in board.goals: initial_lits.add(predicates['is-goal'](*[ TypedEntity("pos-{}-{}".format(spot.x, spot.y), types['location']), ])) else: initial_lits.add(predicates['is-nongoal'](*[ TypedEntity("pos-{}-{}".format(spot.x, spot.y), types['location']), ])) if spot not in board.boxes and spot != board.player: initial_lits.add(predicates['clear'](*[ TypedEntity("pos-{}-{}".format(spot.x, spot.y), types['location']), ])) for another_spot in board.movables: if another_spot == spot: continue else: if another_spot.x == spot.x: if another_spot.y == spot.y + 1: initial_lits.add(predicates['move-dir'](*[ TypedEntity("pos-{}-{}".format(spot.x, spot.y), types['location']), TypedEntity( "pos-{}-{}".format(another_spot.x, another_spot.y), types['location']), DIR_DOWN ])) initial_lits.add(predicates['move-dir'](*[ TypedEntity( "pos-{}-{}".format(another_spot.x, another_spot .y), types['location']), TypedEntity("pos-{}-{}".format(spot.x, spot.y), types['location']), DIR_UP ])) elif another_spot.y == spot.y - 1: initial_lits.add(predicates['move-dir'](*[ TypedEntity("pos-{}-{}".format(spot.x, spot.y), types['location']), TypedEntity( "pos-{}-{}".format(another_spot.x, another_spot.y), types['location']), DIR_UP ])) initial_lits.add(predicates['move-dir'](*[ TypedEntity( "pos-{}-{}".format(another_spot.x, another_spot .y), types['location']), TypedEntity("pos-{}-{}".format(spot.x, spot.y), types['location']), DIR_DOWN ])) elif another_spot.y == spot.y: if another_spot.x == spot.x + 1: initial_lits.add(predicates['move-dir'](*[ TypedEntity("pos-{}-{}".format(spot.x, spot.y), types['location']), TypedEntity( "pos-{}-{}".format(another_spot.x, another_spot.y), types['location']), DIR_RIGHT ])) initial_lits.add(predicates['move-dir'](*[ TypedEntity( "pos-{}-{}".format(another_spot.x, another_spot .y), types['location']), TypedEntity("pos-{}-{}".format(spot.x, spot.y), types['location']), DIR_LEFT ])) elif another_spot.y == spot.y - 1: initial_lits.add(predicates['move-dir'](*[ TypedEntity("pos-{}-{}".format(spot.x, spot.y), types['location']), TypedEntity( "pos-{}-{}".format(another_spot.x, another_spot.y), types['location']), DIR_LEFT ])) initial_lits.add(predicates['move-dir'](*[ TypedEntity( "pos-{}-{}".format(another_spot.x, another_spot .y), types['location']), TypedEntity("pos-{}-{}".format(spot.x, spot.y), types['location']), DIR_RIGHT ])) return frozenset(initial_lits)