Ejemplo n.º 1
0
    def reset(self):
        """
        Set up a new PDDL problem and start a new episode.

        Note that the PDDL files are included in debug_info.

        Returns
        -------
        obs : { Literal }
            The set of active predicates.
        debug_info : dict
            See self._get_debug_info()
        """
        if not self._problem_index_fixed:
            self._problem_idx = self.rng.choice(len(self.problems))
        self._problem = self.problems[self._problem_idx]

        initial_state = State(frozenset(self._problem.initial_state),
                              frozenset(self._problem.objects),
                              self._problem.goal)
        initial_state = self._handle_derived_literals(initial_state)
        self.set_state(initial_state)

        self._goal = self._problem.goal
        debug_info = self._get_debug_info()

        return self.get_state(), debug_info
Ejemplo n.º 2
0
def create_states_from_base_literals(base_state_literals, state_literals,
                                     problem):
    return [
        State(frozenset({*base_state_literals, *literals}),
              frozenset(problem.objects), problem.goal)
        for literals in state_literals
    ]
Ejemplo n.º 3
0
def test_hierarchical_spaces():
    dir_path = os.path.dirname(os.path.realpath(__file__))
    domain_file = os.path.join(dir_path, 'pddl',
                               'hierarchical_type_test_domain.pddl')
    problem_file = os.path.join(dir_path, 'pddl',
                                'hierarchical_type_test_domain',
                                'hierarchical_type_test_problem.pddl')
    domain = PDDLDomainParser(domain_file)
    problem = PDDLProblemParser(problem_file, domain.domain_name, domain.types,
                                domain.predicates, domain.actions)
    actions = list(domain.actions)
    action_predicates = [domain.predicates[a] for a in actions]

    space = LiteralSpace(set(domain.predicates.values()) -
                         set(action_predicates),
                         type_to_parent_types=domain.type_to_parent_types)
    all_ground_literals = space.all_ground_literals(
        State(problem.initial_state, problem.objects, problem.goal))

    ispresent = Predicate("ispresent", 1, [Type("entity")])
    islight = Predicate("islight", 1, [Type("object")])
    isfurry = Predicate("isfurry", 1, [Type("animal")])
    ishappy = Predicate("ishappy", 1, [Type("animal")])
    attending = Predicate("attending", 2, [Type("animal"), Type("object")])

    nomsy = Type("jindo")("nomsy")
    rover = Type("corgi")("rover")
    rene = Type("cat")("rene")
    block1 = Type("block")("block1")
    block2 = Type("block")("block2")
    cylinder1 = Type("cylinder")("cylinder1")

    assert all_ground_literals == {
        ispresent(nomsy),
        ispresent(rover),
        ispresent(rene),
        ispresent(block1),
        ispresent(block2),
        ispresent(cylinder1),
        islight(block1),
        islight(block2),
        islight(cylinder1),
        isfurry(nomsy),
        isfurry(rover),
        isfurry(rene),
        ishappy(nomsy),
        ishappy(rover),
        ishappy(rene),
        attending(nomsy, block1),
        attending(nomsy, block2),
        attending(nomsy, cylinder1),
        attending(rover, block1),
        attending(rover, block2),
        attending(rover, cylinder1),
        attending(rene, block1),
        attending(rene, block2),
        attending(rene, cylinder1),
    }

    print("Test passed.")
Ejemplo n.º 4
0
    def _create_problem_file(self, raw_problem_fname, use_cache=True):
        if (not use_cache) or (raw_problem_fname not in self._problem_files):
            problem_fname = os.path.split(raw_problem_fname)[-1]
            problem_fname = problem_fname.split('.pddl')[0]
            problem_fname += '_{}_with_diffs_{}.pddl'.format(
                self.domain_name, random.randint(0, 9999999))
            problem_fname = os.path.join('/tmp', problem_fname)

            # Parse raw problem
            problem_parser = PDDLProblemParser(raw_problem_fname,
                                               self.domain_name.lower(),
                                               self._types, self._predicates,
                                               self._actions)
            new_initial_state = set(problem_parser.initial_state)

            # Add actions
            action_lits = set(
                self._action_space.all_ground_literals(State(
                    new_initial_state, problem_parser.objects,
                    problem_parser.goal),
                                                       valid_only=False))
            new_initial_state |= action_lits

            # Add 'Different' pairs for each pair of objects
            Different = Predicate('Different', 2)

            for obj1 in problem_parser.objects:
                for obj2 in problem_parser.objects:
                    if obj1 == obj2:
                        continue
                    # if obj1.var_type != obj2.var_type:
                    #     continue
                    diff_lit = Different(obj1, obj2)
                    new_initial_state.add(diff_lit)

            # Write out new temporary problem file
            problem_parser.initial_state = frozenset(new_initial_state)
            problem_parser.write(problem_fname)

            # Add to cache
            self._problem_files[raw_problem_fname] = problem_fname

        return self._problem_files[raw_problem_fname]
Ejemplo n.º 5
0
    def reset(self):
        """
        Set up a new PDDL problem and start a new episode.

        Note that the PDDL files are included in debug_info.

        Returns
        -------
        obs : { Literal }
            The set of active predicates.
        debug_info : dict
            See self._get_debug_info()
        """
        if not self._problem_index_fixed:
            # Problem is changing, force ourselves to recompute heuristic
            self._heuristic = None
            self._problem_idx = self.rng.choice(len(self.problems))
        self._problem = self.problems[self._problem_idx]

        # Create new heuristic if using reward shaping and either the problem
        # isn't fixed or no heuristic has been created yet.
        if (self._shape_reward_mode is not None
                and self._shape_reward_mode != "optimal"
                and self._heuristic is None):
            self._heuristic = self.make_heuristic_function(
                self._shape_reward_mode)

        # reset the current heuristic
        self._current_heuristic = None
        initial_state = State(frozenset(self._problem.initial_state),
                              frozenset(self._problem.objects),
                              self._problem.goal)
        self.set_state(initial_state)

        self._goal = self._problem.goal
        debug_info = self._get_debug_info()

        return self.get_state(), debug_info
Ejemplo n.º 6
0
    def _create_problem_file(self, raw_problem_fname, use_cache=True):
        if (not use_cache) or (raw_problem_fname not in self._problem_files):
            problem_fname = os.path.split(raw_problem_fname)[-1]
            problem_fname = problem_fname.split('.pddl')[0]
            problem_fname += '_{}_with_diffs_{}.pddl'.format(
                self.domain_name, random.randint(0, 9999999))
            problem_fname = os.path.join('/tmp', problem_fname)

            # Parse raw problem
            action_names = [
            ]  # purposely empty b/c we WANT action literals in there
            problem_parser = PDDLProblemParser(raw_problem_fname,
                                               self.domain_name.lower(),
                                               self._types, self._predicates,
                                               action_names)

            # Add action literals (in case they're not already present in the initial state)
            # which will be true when the original domain uses operators_as_actions
            init_state = State(problem_parser.initial_state,
                               problem_parser.objects, None)
            act_lits = self._action_space.all_ground_literals(init_state,
                                                              valid_only=False)
            problem_parser.initial_state = frozenset(
                act_lits | problem_parser.initial_state)

            # Add 'Different' pairs for each pair of objects
            Different = Predicate('Different', 2)
            init_state = set(problem_parser.initial_state)
            for obj1 in problem_parser.objects:
                for obj2 in problem_parser.objects:
                    if obj1 == obj2:
                        continue
                    # if obj1.var_type != obj2.var_type:
                    #     continue
                    diff_lit = Different(obj1, obj2)
                    init_state.add(diff_lit)
            problem_parser.initial_state = frozenset(init_state)
            # Also add 'different' pairs for goal if it's existential
            if isinstance(problem_parser.goal, Exists):
                diffs = []
                for var1 in problem_parser.goal.variables:
                    for var2 in problem_parser.goal.variables:
                        if var1 == var2:
                            continue
                        diffs.append(Different(var1, var2))
                problem_parser.goal = Exists(
                    problem_parser.goal.variables,
                    type(problem_parser.goal.body)(
                        problem_parser.goal.body.literals + diffs))

            # If no objects, write a dummy one to make FF not crash.
            if not problem_parser.objects:
                problem_parser.objects.append("DUMMY")

            # Write out new temporary problem file
            problem_parser.write(problem_fname)

            # Add to cache
            self._problem_files[raw_problem_fname] = (problem_fname,
                                                      problem_parser.objects)

        return self._problem_files[raw_problem_fname]
Ejemplo n.º 7
0
    def _state_to_internal(self, state):
        state = dict(state)
        new_state_literals = set()

        directions_to_deltas = {
            self.direction_type('up') : (-1, 0),
            self.direction_type('down') : (1, 0),
            self.direction_type('left') : (0, -1),
            self.direction_type('right') : (0, 1),
        }

        # conn
        height, width = 6, 6
        for r in range(height):
            for c in range(width):
                loc = self.location_type(f"f{r}-{c}f")
                for direction, (dr, dc) in directions_to_deltas.items():
                    next_r, next_c = r + dr, c + dc
                    if not (0 <= next_r < height and 0 <= next_c < width):
                        continue
                    next_loc = self.location_type(f"f{next_r}-{next_c}f")
                    conn_lit = self.conn(loc, next_loc, direction)
                    new_state_literals.add(conn_lit)

        # at
        occupied_locs = set()
        hospital_loc = None
        for obj_name, loc_tup in state.items():
            if obj_name in ["carrying", "rescue"]:
                continue
            r, c = loc_tup
            loc = self.location_type(f"f{r}-{c}f")
            if obj_name.startswith("person"):
                at_pred = self.person_at
            elif obj_name.startswith("robot"):
                at_pred = self.robot_at
                occupied_locs.add((r, c))
            elif obj_name.startswith("wall"):
                at_pred = self.wall_at
                occupied_locs.add((r, c))
            elif obj_name.startswith("hospital"):
                at_pred = self.hospital_at
                assert hospital_loc is None
                hospital_loc = loc
            else:
                raise Exception(f"Unrecognized object {obj_name}")
            new_state_literals.add(at_pred(obj_name, loc))
        assert hospital_loc is not None

        # carrying/handsfree
        if state["carrying"] is None:
            new_state_literals.add(self.handsfree("robot0"))
        else:
            new_state_literals.add(self.carrying("robot0", state["carrying"]))

        # clear
        for r in range(height):
            for c in range(width):
                if (r, c) not in occupied_locs:
                    loc = self.location_type(f"f{r}-{c}f")
                    clear_lit = self.clear(loc)
                    new_state_literals.add(clear_lit)

        # objects
        new_objects = frozenset({o for lit in new_state_literals for o in lit.variables })

        # goal
        new_goal = LiteralConjunction([self.person_at(person, hospital_loc) \
            for person in sorted(state["rescue"])])

        new_state = State(frozenset(new_state_literals), new_objects, new_goal)

        return new_state
Ejemplo n.º 8
0
 def __call__(self, domain, state, timeout):
     act_preds = [domain.predicates[a] for a in list(domain.actions)]
     act_space = LiteralSpace(
         act_preds, type_to_parent_types=domain.type_to_parent_types)
     dom_file = tempfile.NamedTemporaryFile(delete=False).name
     prob_file = tempfile.NamedTemporaryFile(delete=False).name
     domain.write(dom_file)
     lits = set(state.literals)
     if not domain.operators_as_actions:
         lits |= set(act_space.all_ground_literals(state, valid_only=False))
     PDDLProblemParser.create_pddl_file(prob_file,
                                        state.objects,
                                        lits,
                                        "myproblem",
                                        domain.domain_name,
                                        state.goal,
                                        fast_downward_order=True)
     cur_objects = set()
     start_time = time.time()
     if self._force_include_goal_objects:
         # Always start off considering objects in the goal.
         for lit in state.goal.literals:
             cur_objects |= set(lit.variables)
     # Get scores once.
     object_to_score = {
         obj: self._guidance.score_object(obj, state)
         for obj in state.objects if obj not in cur_objects
     }
     # Initialize threshold.
     threshold = self._gamma
     for _ in range(self._max_iterations):
         # Find new objects by incrementally lowering threshold.
         unused_objs = sorted(list(state.objects - cur_objects))
         new_objs = set()
         while unused_objs:
             # Geometrically lower threshold.
             threshold *= self._gamma
             # See if there are any new objects.
             new_objs = {
                 o
                 for o in unused_objs if object_to_score[o] > threshold
             }
             # If there are, try planning with them.
             if new_objs:
                 break
         cur_objects |= new_objs
         # Keep only literals referencing currently considered objects.
         cur_lits = set()
         for lit in state.literals:
             if all(var in cur_objects for var in lit.variables):
                 cur_lits.add(lit)
         dummy_state = State(cur_lits, cur_objects, state.goal)
         # Try planning with only this object set.
         print("[Trying to plan with {} objects of {} total, "
               "threshold is {}...]".format(len(cur_objects),
                                            len(state.objects), threshold),
               flush=True)
         try:
             time_elapsed = time.time() - start_time
             # Get a plan from base planner & validate it.
             plan = self._planner(domain, dummy_state,
                                  timeout - time_elapsed)
             if not validate_strips_plan(domain_file=dom_file,
                                         problem_file=prob_file,
                                         plan=plan):
                 raise PlanningFailure("Invalid plan")
         except PlanningFailure:
             # Try again with more objects.
             if len(cur_objects) == len(state.objects):
                 # We already tried with all objects, give up.
                 break
             continue
         return plan
     raise PlanningFailure("Plan not found! Reached max_iterations.")