示例#1
0
 def _parse_domain_types(self):
     match = re.search(r"\(:types", self.domain)
     if not match:
         self.types = {"default": Type("default")}
         self.uses_typing = False
         return
     self.uses_typing = True
     start_ind = match.start()
     types = self._find_balanced_expression(self.domain, start_ind)
     types = types[7:-1].split()
     self.types = {type_name: Type(type_name) for type_name in types}
示例#2
0
 def _parse_domain_types(self):
     match = re.search(r"\(:types", self.domain)
     if not match:
         self.types = {"default": Type("default")}
         self.type_hierarchy = {}
         self.uses_typing = False
         return
     self.uses_typing = True
     start_ind = match.start()
     types = self._find_balanced_expression(self.domain, start_ind)
     # Non-hierarchical types
     if " - " not in types:
         types = types[7:-1].split()
         self.types = {type_name: Type(type_name) for type_name in types}
         self.type_hierarchy = {}
     # Hierarchical types
     else:
         self.types = {}
         self.type_hierarchy = {}
         remaining_type_str = types[7:-1]
         while " - " in remaining_type_str:
             dash_index = remaining_type_str.index(" - ")
             s = remaining_type_str[dash_index:]
             super_start_index = dash_index + len(s) - len(s.lstrip()) + 2
             s = remaining_type_str[super_start_index:]
             try:
                 end_index_offset = min(s.index(" "), s.index("\n"))
             except ValueError:
                 end_index_offset = len(s)
             super_end_index = super_start_index + end_index_offset
             super_type_name = remaining_type_str[
                 super_start_index:super_end_index]
             sub_type_names = remaining_type_str[:dash_index].split()
             # Add new types
             for new_type in sub_type_names + [super_type_name]:
                 if new_type not in self.types:
                     self.types[new_type] = Type(new_type)
             # Add to hierarchy
             super_type = self.types[super_type_name]
             if super_type in self.type_hierarchy:
                 self.type_hierarchy[super_type].update(
                     {self.types[t]
                      for t in sub_type_names})
             else:
                 self.type_hierarchy[super_type] = {
                     self.types[t]
                     for t in sub_type_names
                 }
             remaining_type_str = remaining_type_str[super_end_index:]
         assert len(remaining_type_str.strip(
         )) == 0, "Cannot mix hierarchical and non-hierarchical types"
示例#3
0
 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)
示例#4
0
 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)
示例#5
0
def test_zero_arity_negative_preconditions():
    MoveableType = Type('moveable')
    Holding = Predicate('Holding', 1, var_types=[MoveableType])
    HandEmpty = Predicate('HandEmpty', 0, var_types=[])

    conds = [Holding("?x1"), Not(HandEmpty())]
    kb = {Holding("a"), HandEmpty()}
    assignments = find_satisfying_assignments(kb,
                                              conds,
                                              allow_redundant_variables=False)
    assert len(assignments) == 0

    print("Pass.")
示例#6
0
def test_determinize():
    dir_path = os.path.dirname(os.path.realpath(__file__))
    domain_file = os.path.join(dir_path, 'pddl',
                               'test_probabilistic_domain.pddl')
    problem_dir = os.path.join(dir_path, 'pddl', 'test_probabilistic_domain')

    env = PDDLEnv(domain_file,
                  problem_dir,
                  raise_error_on_invalid_action=True,
                  dynamic_action_space=True)
    env.domain.determinize()

    obs, _ = env.reset()
    action = env.action_space.all_ground_literals(obs).pop()
    transitions = env.get_all_possible_transitions(action, return_probs=True)

    transition_list = list(transitions)
    assert len(transition_list) == 1
    assert transition_list[0][1] == 1.0
    newstate = transition_list[0][0][0]

    type1 = Type('type1')
    type2 = Type('type2')
    pred1 = Predicate('pred1', 1, [type1])
    pred2 = Predicate('pred2', 1, [type2])
    pred3 = Predicate('pred3', 3, [type1, type2, type2])

    assert newstate.literals == frozenset({
        pred1('b2'),
        pred2('c1'),
        pred3('a1', 'c1', 'd1'),
        pred3('a2', 'c2', 'd2'),
        pred3('b2', 'd1', 'c1')
    })

    print("Test passed.")
示例#7
0
def test_heuristic():
    dir_path = os.path.dirname(os.path.realpath(__file__))
    domain_file = os.path.join(dir_path, 'pddl', 'easyblocks.pddl')
    problem_dir = os.path.join(dir_path, 'pddl', 'easyblocks')

    block = Type("block")
    pickup = Predicate("pickup", 1, [block])
    stack = Predicate("stack", 2, [block, block])

    shaped_env = PDDLEnv(
        domain_file,
        problem_dir,
        shape_reward_mode="lmcut",
        raise_error_on_invalid_action=True,
    )
    env = PDDLEnv(
        domain_file,
        problem_dir,
        shape_reward_mode=None,
        raise_error_on_invalid_action=True,
    )
    shaped_env.reset()
    env.reset()

    _, rew, _, _ = env.step(pickup("b"))
    _, shaped_rew, _, _ = shaped_env.step(pickup("b"))

    assert rew == 0.
    assert shaped_rew == 1.
    intermediate_state = env.get_state()

    def assert_last_step():
        _, rew, done, _ = env.step(stack("b", "a"))
        _, shaped_rew, shaped_done, _ = shaped_env.step(stack("b", "a"))
        assert done
        assert shaped_done
        assert rew == 1.
        assert shaped_rew == 2.

    # check if the step to the goal is terminal and with correct rewards
    assert_last_step()

    # check if shaped reward is consistent after setting the state
    shaped_env.set_state(intermediate_state)
    env.set_state(intermediate_state)
    assert_last_step()

    print("Test passed.")
示例#8
0
def test_negative_preconditions():
    MoveableType = Type('moveable')
    Holding = Predicate('Holding', 1, var_types=[MoveableType])
    IsPawn = Predicate('IsPawn', 1, var_types=[MoveableType])
    PutOn = Predicate('PutOn', 1, var_types=[MoveableType])
    On = Predicate('On', 2, var_types=[MoveableType, MoveableType])

    # ?x0 must bind to o0 and ?x1 must bind to o1, so ?x2 must bind to o2
    conds = [
        PutOn("?x0"),
        Holding("?x1"),
        IsPawn("?x2"),
        Not(On("?x2", "?x0"))
    ]
    kb = {
        PutOn('o0'),
        IsPawn('o0'),
        IsPawn('o1'),
        IsPawn('o2'),
        Holding('o1'),
    }
    assignments = find_satisfying_assignments(kb,
                                              conds,
                                              allow_redundant_variables=False)
    assert len(assignments) == 1

    # should be the same, even though IsPawn("?x2") is removed
    conds = [PutOn("?x0"), Holding("?x1"), Not(On("?x2", "?x0"))]
    kb = {
        PutOn('o0'),
        IsPawn('o0'),
        IsPawn('o1'),
        IsPawn('o2'),
        Holding('o1'),
    }
    assignments = find_satisfying_assignments(kb,
                                              conds,
                                              allow_redundant_variables=False)
    assert len(assignments) == 1

    print("Pass.")
示例#9
0
 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)
示例#10
0
def test_pddlenv_hierarchical_types():
    dir_path = os.path.dirname(os.path.realpath(__file__))
    domain_file = os.path.join(dir_path, 'pddl',
                               'hierarchical_type_test_domain.pddl')
    problem_dir = os.path.join(dir_path, 'pddl',
                               'hierarchical_type_test_domain')

    env = PDDLEnv(domain_file, problem_dir)
    obs, _ = env.reset()

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

    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 obs.literals == frozenset({
        ispresent(nomsy),
        ispresent(rover),
        ispresent(rene),
        ispresent(block1),
        ispresent(block2),
        ispresent(cylinder1),
        islight(block1),
        islight(cylinder1),
        isfurry(nomsy),
    })

    obs, _, _, _ = env.step(pet('block1'))

    assert obs.literals == frozenset({
        ispresent(nomsy),
        ispresent(rover),
        ispresent(rene),
        ispresent(block1),
        ispresent(block2),
        ispresent(cylinder1),
        islight(block1),
        islight(cylinder1),
        isfurry(nomsy),
    })

    obs, _, _, _ = env.step(pet(nomsy))

    assert obs.literals == frozenset({
        ispresent(nomsy),
        ispresent(rover),
        ispresent(rene),
        ispresent(block1),
        ispresent(block2),
        ispresent(cylinder1),
        islight(block1),
        islight(cylinder1),
        isfurry(nomsy),
        ishappy(nomsy)
    })

    print("Test passed.")
示例#11
0
def test_prover():
    TType = Type('t')
    atom0, atom1, atom2 = TType('atom0'), TType('atom1'), TType('atom2')
    var0, var1, var2, var3 = TType('Var0'), TType('Var1'), TType(
        'Var2'), TType('Var3')

    # Single predicate single arity test
    predicate0 = Predicate('Predicate0', 1, [TType])
    predicate1 = Predicate('Predicate1', 2, [TType, TType])
    predicate2 = Predicate('Predicate2', 1, [TType])

    kb0 = [predicate0(atom0)]
    assignments = find_satisfying_assignments(kb0, [predicate0(var0)])
    assert len(assignments) == 1
    assert len(assignments[0]) == 1
    assert assignments[0][var0] == atom0

    assignments = find_satisfying_assignments(
        kb0, [predicate0(var0), predicate0(var1)])
    assert len(assignments) == 1

    kb1 = [predicate0(atom0), predicate0(atom1)]

    assignments = find_satisfying_assignments(kb1, [predicate0(var0)])
    assert len(assignments) == 2

    assignments = find_satisfying_assignments(
        kb1, [predicate0(var0), predicate0(var1)])
    assert len(assignments) == 2

    assignments = find_satisfying_assignments(
        kb1, [predicate0(var0),
              predicate0(var1),
              predicate0(var2)])
    assert len(assignments) == 2

    kb2 = [predicate0(atom0), predicate0(atom1), predicate0(atom2)]

    assignments = find_satisfying_assignments(kb2, [predicate0(var0)])
    assert len(assignments) == 2

    assignments = find_satisfying_assignments(
        kb2, [predicate0(var0), predicate0(var1)])
    assert len(assignments) == 2

    assignments = find_satisfying_assignments(
        kb2, [predicate0(var0),
              predicate0(var1),
              predicate0(var2)])
    assert len(assignments) == 2

    # Single predicate multiple arity test
    kb3 = [predicate1(atom0, atom1), predicate1(atom1, atom2)]

    assignments = find_satisfying_assignments(kb3, [predicate1(var0, var1)])
    assert len(assignments) == 2

    assignments = find_satisfying_assignments(
        kb3, [predicate1(var0, var1),
              predicate1(var1, var2)])
    assert len(assignments) == 1

    assignments = find_satisfying_assignments(
        kb3, [predicate1(var0, var1),
              predicate1(var1, var0)])
    assert len(assignments) == 0

    assignments = find_satisfying_assignments(
        kb3, [predicate1(var0, var1),
              predicate1(var2, var3)])
    assert len(assignments) == 2

    ## Multiple predicate multiple arity test
    kb4 = [
        predicate0(atom2),
        predicate1(atom0, atom1),
        predicate1(atom1, atom2)
    ]

    assignments = find_satisfying_assignments(
        kb4, [predicate1(var0, var1),
              predicate0(var1),
              predicate0(var0)])
    assert len(assignments) == 0

    ## Tricky case!
    kb6 = [
        predicate0(atom0),
        predicate2(atom1),
        predicate1(atom0, atom2),
        predicate1(atom2, atom1)
    ]

    assignments = find_satisfying_assignments(
        kb6, [predicate0(var0),
              predicate2(var1),
              predicate1(var0, var1)])
    assert len(assignments) == 0

    print("Pass.")
示例#12
0
def get_sar_successor_state(state, action):
    """Search and rescue specific successor generation

    Assumptions:
        - One robot called robot0
    """
    # Remake predicates to keep this function self-contained
    person_type = Type('person')
    robot_type = Type('robot')
    location_type = Type('location')
    direction_type = Type('direction')
    clear = Predicate('clear', 1, [location_type])
    conn = Predicate("conn", 3, [location_type, location_type, direction_type])
    robot_at = Predicate('robot-at', 2, [robot_type, location_type])
    carrying = Predicate('carrying', 2, [robot_type, person_type])
    person_at = Predicate('person-at', 2, [person_type, location_type])
    handsfree = Predicate('handsfree', 1, [robot_type])

    # Parse the state
    robot_location = None # location
    robot_carrying = None # person
    adjacency_map = {} # (location, direction) -> location
    people_locs = {} # person -> location
    clear_locs = set()

    for lit in state.literals:
        if lit.predicate.name == "robot-at":
            assert lit.variables[0] == "robot0"
            robot_location = lit.variables[1]
        elif lit.predicate.name == "conn":
            adjacency_map[(lit.variables[0], lit.variables[2])] = lit.variables[1]
        elif lit.predicate.name == "carrying":
            assert lit.variables[0] == "robot0"
            robot_carrying = lit.variables[1]
        elif lit.predicate.name == "person-at":
            people_locs[lit.variables[0]] = lit.variables[1]
        elif lit.predicate.name == "clear":
            clear_locs.add(lit.variables[0])

    assert robot_location is not None

    is_valid = False
    pos_preconds = set()
    neg_preconds = set()
    pos_effects = set()
    neg_effects = set()

    if action.predicate.name == "move":
        """
        (:action move-robot
        :parameters (?robot - robot ?from - location ?to - location ?dir - direction)
        :precondition (and (move ?dir)
            (conn ?from ?to ?dir)
            (robot-at ?robot ?from)
            (clear ?to))
        :effect (and
            (not (robot-at ?robot ?from))
            (robot-at ?robot ?to)
            (not (clear ?to))
            (clear ?from))
        )
        """
        direction = action.variables[0]
        if (robot_location, direction) in adjacency_map:
            next_robot_location = adjacency_map[(robot_location, direction)]
            if next_robot_location in clear_locs:
                is_valid = True
                pos_preconds = { 
                    conn(robot_location, next_robot_location, direction),
                    robot_at("robot0", robot_location),
                    clear(next_robot_location),
                }
                pos_effects = {
                    robot_at("robot0", next_robot_location),
                    clear(robot_location)
                }
                neg_effects = {
                    robot_at("robot0", robot_location),
                    clear(next_robot_location)
                }

    elif action.predicate.name == "pickup":
        """
        (:action pickup-person
            :parameters (?robot - robot ?person - person ?loc - location)
            :precondition (and (pickup ?person)
                (robot-at ?robot ?loc)
                (person-at ?person ?loc)
                (handsfree ?robot))
            :effect (and
                (not (person-at ?person ?loc))
                (not (handsfree ?robot))
                (carrying ?robot ?person))
        )
        """
        if robot_carrying is None:
            person = action.variables[0]
            person_loc = people_locs[person]
            if person_loc == robot_location:
                is_valid = True
                pos_preconds = { 
                    robot_at("robot0", robot_location),
                    person_at(person, person_loc),
                    handsfree("robot0"),
                }
                pos_effects = {
                    carrying("robot0", person),
                }
                neg_effects = {
                    person_at(person, person_loc),
                    handsfree("robot0"),
                }

    elif action.predicate.name == "dropoff":
        """
        (:action dropoff-person
        :parameters (?robot - robot ?person - person ?loc - location)
        :precondition (and (dropoff )
            (carrying ?robot ?person)
            (robot-at ?robot ?loc))
        :effect (and
            (person-at ?person ?loc)
            (handsfree ?robot)
            (not (carrying ?robot ?person)))
        )
        """
        if robot_carrying is not None:
            is_valid = True
            pos_preconds = { 
                robot_at("robot0", robot_location),
                carrying("robot0", robot_carrying),
            }
            pos_effects = {
                person_at(robot_carrying, robot_location),
                handsfree("robot0"),
            }
            neg_effects = {
                carrying("robot0", robot_carrying),
            }

    else:
        raise Exception(f"Unrecognized action {action}.")

    if not is_valid:
        return state

    assert state.literals.issuperset(pos_preconds)
    assert len(state.literals & {Not(p) for p in neg_preconds}) == 0
    new_state_literals = set(state.literals)
    new_state_literals -= neg_effects
    new_state_literals |= pos_effects
    return state.with_literals(frozenset(new_state_literals))
示例#13
0
class SearchAndRescueEnv(PDDLSearchAndRescueEnv):
    """Changes the state space to just be positions of objects
    and the identity of the person being carried.
    """
    person_type = Type('person')
    robot_type = Type('robot')
    location_type = Type('location')
    direction_type = Type('direction')
    wall_type = Type('wall')
    hospital_type = Type('hospital')
    clear = Predicate('clear', 1, [location_type])
    conn = Predicate("conn", 3, [location_type, location_type, direction_type])
    robot_at = Predicate('robot-at', 2, [robot_type, location_type])
    person_at = Predicate('person-at', 2, [person_type, location_type])
    wall_at = Predicate('wall-at', 2, [wall_type, location_type])
    hospital_at = Predicate('hospital-at', 2, [hospital_type, location_type])
    carrying = Predicate('carrying', 2, [robot_type, person_type])
    handsfree = Predicate('handsfree', 1, [robot_type])

    @property
    def observation_space(self):
        raise NotImplementedError()

    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

    def _internal_to_state(self, internal_state):
        state = { "carrying" : None }
        state["rescue"] = set()
        for lit in internal_state.goal.literals:
            assert lit.predicate == self.person_at
            state["rescue"].add(lit.variables[0].name)
        state["rescue"] = frozenset(state["rescue"]) # make hashable
        for lit in internal_state.literals:
            if lit.predicate.name.endswith("at"):
                obj_name = lit.variables[0].name
                r, c = self._loc_to_rc(lit.variables[1])
                state[obj_name] = (r, c)
            if lit.predicate.name == "carrying":
                person_name = lit.variables[1].name
                state["carrying"] = person_name
        state = tuple(sorted(state.items())) # make hashable
        return state

    def _loc_to_rc(self, loc_str):
        assert loc_str.startswith("f") and loc_str.endswith("f")
        r, c = loc_str[1:-1].split('-')
        return (int(r), int(c))

    def set_state(self, state):
        assert isinstance(state, State), "Do not call set_state"
        self._state = state

    def get_state(self):
        assert isinstance(self._state, State), "Do not call get_state"
        return self._state

    def reset(self):
        internal_state, debug_info = super().reset()
        return self._internal_to_state(internal_state), debug_info

    def step(self, action):
        internal_state, reward, done, debug_info = super().step(action)
        state = self._internal_to_state(internal_state)
        return state, reward, done, debug_info

    def get_successor_state(self, state, action):
        internal_state = self._state_to_internal(state)
        next_internal_state = super().get_successor_state(internal_state, action)
        next_state = self._internal_to_state(next_internal_state)
        # Sanity checks
        assert state == self._internal_to_state(internal_state)
        assert next_internal_state == self._state_to_internal(next_state)
        return next_state

    def render_from_state(self, state):
        internal_state = self._state_to_internal(state)
        return super().render_from_state(internal_state)

    def check_goal(self, state):
        internal_state = self._state_to_internal(state)
        return super().check_goal(internal_state)
示例#14
0
from ndr.ndrs import *
from ndr.learn import *
from pddlgym.structs import Type, Anti
from ndr.main import *
from ndr.utils import nostdout
import gym
import pddlgym
import pybullet_abstraction_envs
import numpy as np

VERBOSE = True

# Some shared stuff
block_type = Type("block")
Act0 = Predicate("act0", 0, [])
Act01 = Predicate("act01", 0, [])
Act1 = Predicate("act1", 0, [block_type])
Red = Predicate("red", 1, [block_type])
Blue = Predicate("blue", 1, [block_type])
HandsFree0 = Predicate("HandsFree0", 0, [])

MoveableType = Type('moveable')
StaticType = Type('static')
IsRobot = Predicate('IsRobot', 1, var_types=[MoveableType])
IsBear = Predicate('IsBear', 1, var_types=[MoveableType])
IsHoney = Predicate('IsHoney', 1, var_types=[MoveableType])
IsPawn = Predicate('IsPawn', 1, var_types=[MoveableType])
IsMonkey = Predicate('IsMonkey', 1, var_types=[MoveableType])
IsGoal = Predicate('IsGoal', 1, var_types=[StaticType])
At = Predicate('At', 2, var_types=[MoveableType, StaticType])
Holding = Predicate('Holding', 1, var_types=[MoveableType])
示例#15
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)
    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)
    space.update(problem.objects)
    all_ground_literals = space.all_ground_literals()

    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.")
示例#16
0
def test_hierarchical_types():
    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)

    assert set(domain.types.keys()) == {
        Type("dog"),
        Type("cat"),
        Type("animal"),
        Type("block"),
        Type("cylinder"),
        Type("jindo"),
        Type("corgi"),
        Type("object"),
        Type("entity")
    }

    assert domain.type_hierarchy == {
        Type("animal"): {Type("dog"), Type("cat")},
        Type("dog"): {Type("jindo"), Type("corgi")},
        Type("object"): {Type("block"), Type("cylinder")},
        Type("entity"): {Type("object"), Type("animal")},
    }

    assert domain.type_to_parent_types == {
        Type("entity"): {Type("entity")},
        Type("object"): {Type("object"), Type("entity")},
        Type("animal"): {Type("animal"), Type("entity")},
        Type("dog"): {Type("dog"), Type("animal"),
                      Type("entity")},
        Type("cat"): {Type("cat"), Type("animal"),
                      Type("entity")},
        Type("corgi"):
        {Type("corgi"),
         Type("dog"),
         Type("animal"),
         Type("entity")},
        Type("jindo"):
        {Type("jindo"),
         Type("dog"),
         Type("animal"),
         Type("entity")},
        Type("block"): {Type("block"),
                        Type("object"),
                        Type("entity")},
        Type("cylinder"): {Type("cylinder"),
                           Type("object"),
                           Type("entity")},
    }

    print("Test passed.")
示例#17
0
def test_get_all_possible_transitions():
    dir_path = os.path.dirname(os.path.realpath(__file__))
    domain_file = os.path.join(dir_path, 'pddl',
                               'test_probabilistic_domain.pddl')
    problem_dir = os.path.join(dir_path, 'pddl', 'test_probabilistic_domain')

    env = PDDLEnv(domain_file,
                  problem_dir,
                  raise_error_on_invalid_action=True,
                  dynamic_action_space=True)

    obs, _ = env.reset()
    action = env.action_space.all_ground_literals(obs).pop()
    transitions = env.get_all_possible_transitions(action)

    transition_list = list(transitions)
    assert len(transition_list) == 2
    state1, state2 = transition_list[0][0], transition_list[1][0]

    type1 = Type('type1')
    type2 = Type('type2')
    pred1 = Predicate('pred1', 1, [type1])
    pred2 = Predicate('pred2', 1, [type2])
    pred3 = Predicate('pred3', 3, [type1, type2, type2])

    state1, state2 = (state1,
                      state2) if pred2('c1') in state2.literals else (state2,
                                                                      state1)

    assert state1.literals == frozenset({
        pred1('b2'),
        pred3('a1', 'c1', 'd1'),
        pred3('a2', 'c2', 'd2'),
        pred3('b2', 'd1', 'c1')
    })
    assert state2.literals == frozenset({
        pred1('b2'),
        pred2('c1'),
        pred3('a1', 'c1', 'd1'),
        pred3('a2', 'c2', 'd2'),
        pred3('b2', 'd1', 'c1')
    })

    # Now test again with return_probs=True.
    transitions = env.get_all_possible_transitions(action, return_probs=True)

    transition_list = list(transitions)
    assert len(transition_list) == 2
    assert abs(transition_list[0][1] -
               0.3) < 1e-5 or abs(transition_list[0][1] - 0.7) < 1e-5
    assert abs(transition_list[1][1] -
               0.3) < 1e-5 or abs(transition_list[1][1] - 0.7) < 1e-5
    assert abs(transition_list[0][1] - transition_list[1][1]) > 0.3
    state1, state2 = transition_list[0][0][0], transition_list[1][0][0]

    type1 = Type('type1')
    type2 = Type('type2')
    pred1 = Predicate('pred1', 1, [type1])
    pred2 = Predicate('pred2', 1, [type2])
    pred3 = Predicate('pred3', 3, [type1, type2, type2])

    state1, state2 = (state1,
                      state2) if pred2('c1') in state2.literals else (state2,
                                                                      state1)

    assert state1.literals == frozenset({
        pred1('b2'),
        pred3('a1', 'c1', 'd1'),
        pred3('a2', 'c2', 'd2'),
        pred3('b2', 'd1', 'c1')
    })
    assert state2.literals == frozenset({
        pred1('b2'),
        pred2('c1'),
        pred3('a1', 'c1', 'd1'),
        pred3('a2', 'c2', 'd2'),
        pred3('b2', 'd1', 'c1')
    })

    print("Test passed.")
示例#18
0
def test_get_all_possible_transitions_multiple_effects():
    dir_path = os.path.dirname(os.path.realpath(__file__))
    domain_file = os.path.join(dir_path, 'pddl',
                               'test_probabilistic_domain_alt_2.pddl')
    problem_dir = os.path.join(dir_path, 'pddl',
                               'test_probabilistic_domain_alt_2')

    env = PDDLEnv(domain_file,
                  problem_dir,
                  raise_error_on_invalid_action=True,
                  dynamic_action_space=True)

    obs, _ = env.reset()
    action = env.action_space.all_ground_literals(obs).pop()
    transitions = env.get_all_possible_transitions(action)

    transition_list = list(transitions)
    assert len(transition_list) == 3

    states = set({
        transition_list[0][0].literals, transition_list[1][0].literals,
        transition_list[2][0].literals
    })

    type1 = Type('type1')
    type2 = Type('type2')
    pred1 = Predicate('pred1', 1, [type1])
    pred2 = Predicate('pred2', 1, [type2])
    pred3 = Predicate('pred3', 3, [type1, type2, type2])

    expected_states = set({
        frozenset(
            {pred1('b2'),
             pred3('a1', 'c1', 'd1'),
             pred3('a2', 'c2', 'd2')}),
        frozenset(
            {pred2('c1'),
             pred3('a1', 'c1', 'd1'),
             pred3('a2', 'c2', 'd2')}),
        frozenset({
            pred1('b2'),
            pred2('c1'),
            pred3('a1', 'c1', 'd1'),
            pred3('a2', 'c2', 'd2'),
            pred3('b2', 'd1', 'c1')
        })
    })

    assert states == expected_states

    # Now test again with return_probs=True.
    transitions = env.get_all_possible_transitions(action, return_probs=True)

    transition_list = list(transitions)
    assert len(transition_list) == 3
    states_and_probs = {
        transition_list[0][0][0].literals: transition_list[0][1],
        transition_list[1][0][0].literals: transition_list[1][1],
        transition_list[2][0][0].literals: transition_list[2][1]
    }

    type1 = Type('type1')
    type2 = Type('type2')
    pred1 = Predicate('pred1', 1, [type1])
    pred2 = Predicate('pred2', 1, [type2])
    pred3 = Predicate('pred3', 3, [type1, type2, type2])

    expected_states = {
        frozenset({
            pred1('b2'),
            pred3('a1', 'c1', 'd1'),
            pred3('a2', 'c2', 'd2')
        }):
        0.5,
        frozenset({
            pred2('c1'),
            pred3('a1', 'c1', 'd1'),
            pred3('a2', 'c2', 'd2')
        }):
        0.4,
        frozenset({
            pred1('b2'),
            pred2('c1'),
            pred3('a1', 'c1', 'd1'),
            pred3('a2', 'c2', 'd2'),
            pred3('b2', 'd1', 'c1')
        }):
        0.1
    }

    for s, prob in states_and_probs.items():
        assert s in expected_states
        assert prob - expected_states[s] < 1e-5

    print("Test passed.")
示例#19
0
def integration_test():
    dir_path = os.path.dirname(os.path.realpath(__file__))
    domain_file = os.path.join(dir_path, 'pddl', 'test_domain.pddl')
    problem_file = os.path.join(dir_path, 'pddl', 'test_domain', 'test_problem.pddl')
    domain = PDDLDomainParser(domain_file)
    problem = PDDLProblemParser(problem_file, domain.domain_name, domain.types,
        domain.predicates)

    ## Check domain
    type1 = Type('type1')
    type2 = Type('type2')

    # Action predicates
    action_pred = Predicate('actionpred', 1, [type1])

    # Predicates
    pred1 = Predicate('pred1', 1, [type1])
    pred2 = Predicate('pred2', 1, [type2])
    pred3 = Predicate('pred3', 1, [type1, type2, type2])
    assert set(domain.predicates.values()) == { pred1, pred2, pred3, action_pred }
    assert domain.actions == { action_pred.name }

    # Operators
    assert len(domain.operators) == 1
    operator1 = Predicate('action1', 4, [type1, type1, type2, type2])
    assert operator1 in domain.operators

    operator = domain.operators[operator1]
    # Operator parameters
    assert len(operator.params) == 4
    assert operator.params[0] == type1('?a')
    assert operator.params[1] == type1('?b')
    assert operator.params[2] == type2('?c')
    assert operator.params[3] == type2('?d')

    # Operator preconditions (set of Literals)
    assert len(operator.preconds.literals) == 4
    assert set(operator.preconds.literals) == { action_pred('?b'), pred1('?b'), 
        pred3('?a', '?c', '?d'), Not(pred2('?c')) }

    # Operator effects (set of Literals)
    assert len(operator.effects.literals) == 3
    assert set(operator.effects.literals) == { Anti(pred2('?d')), pred2('?c'), 
        pred3('?b', '?d', '?c')}

    ## Check problem

    # Objects
    assert set(problem.objects) == {type1('a1'), type1('a2'), type1('b1'),
        type1('b2'), type1('b3'), type2('c1'), type2('c2'), type2('d1'), 
        type2('d2'), type2('d3')}

    # Goal
    assert isinstance(problem.goal, LiteralConjunction)
    assert set(problem.goal.literals) == {pred2('c2'), pred3('b1', 'c1', 'd1')}

    # Init
    assert problem.initial_state == { pred1('b2'), pred2('c1'),
        pred3('a1', 'c1', 'd1'), pred3('a2', 'c2', 'd2'), action_pred('a1'), 
        action_pred('a2'), action_pred('b1'), action_pred('b2')}

    print("Test passed.")
示例#20
0
def test_pddlenv():
    dir_path = os.path.dirname(os.path.realpath(__file__))
    domain_file = os.path.join(dir_path, 'pddl', 'test_domain.pddl')
    problem_dir = os.path.join(dir_path, 'pddl', 'test_domain')

    env = PDDLEnv(domain_file,
                  problem_dir,
                  raise_error_on_invalid_action=True,
                  dynamic_action_space=True)
    env2 = PDDLEnv(domain_file,
                   problem_dir,
                   raise_error_on_invalid_action=True,
                   dynamic_action_space=False)

    type1 = Type('type1')
    type2 = Type('type2')
    pred1 = Predicate('pred1', 1, [type1])
    pred2 = Predicate('pred2', 1, [type2])
    pred3 = Predicate('pred3', 1, [type1, type2, type2])
    operator_name = 'action1'
    action_pred = Predicate('actionpred', 1, [type1])

    obs, _ = env.reset()

    assert obs == {
        pred1('b2'),
        pred2('c1'),
        pred3('a1', 'c1', 'd1'),
        pred3('a2', 'c2', 'd2')
    }

    operator = env.domain.operators[operator_name]

    # Invalid action
    action = action_pred('b1')

    try:
        env.step(action)
        assert False, "Action was supposed to be invalid"
    except InvalidAction:
        pass

    assert action not in env.action_space.all_ground_literals(
    ), "Dynamic action space not working"
    env2.reset()
    assert action in env2.action_space.all_ground_literals(
    ), "Dynamic action space not working"

    # Valid args
    action = action_pred('b2')

    obs, _, _, _ = env.step(action)

    assert obs == {
        pred1('b2'),
        pred2('c1'),
        pred2('c2'),
        pred3('b2', 'd2', 'c2'),
        pred3('a1', 'c1', 'd1'),
        pred3('a2', 'c2', 'd2')
    }

    print("Test passed.")