Ejemplo n.º 1
0
    def check_state(self, state: State) -> bool:
        """Check that a state satisfies the constraints."""

        fail = Proposition("fail", [])

        constraints = state.all_applicable_actions(self.constraints)
        for constraint in constraints:
            if state.is_applicable(constraint):
                # Optimistically delay copying the state
                copy = state.copy()
                copy.apply(constraint)

                if copy.is_fact(fail):
                    return False

        return True
Ejemplo n.º 2
0
def test_get_reverse_action():
    kb = KnowledgeBase.default()
    for rule in kb.rules.values():
        empty_state = State(KnowledgeBase.default().logic)
        action = maybe_instantiate_variables(rule, kb.types.constants_mapping.copy(), empty_state)
        r_action = kb.get_reverse_action(action)

        if rule.name.startswith("eat"):
            assert r_action is None
        else:
            assert r_action is not None

            # Check if that when applying the reverse rule we can re-obtain
            # the previous state.
            state = State(KnowledgeBase.default().logic, action.preconditions)

            new_state = state.copy()
            assert new_state.apply(action)

            r_state = new_state.copy()
            r_state.apply(r_action)
            assert state == r_state
Ejemplo n.º 3
0
def test_get_reverse_rules(verbose=False):
    for rule in data.get_rules().values():
        r_rule = data.get_reverse_rules(rule)

        if verbose:
            print(rule, r_rule)

        if rule.name.startswith("eat"):
            assert r_rule is None
        else:
            # Check if that when applying the reverse rule we can reobtain
            # the previous state.
            action = maybe_instantiate_variables(
                rule,
                data.get_types().constants_mapping.copy(), State([]))
            state = State(action.preconditions)

            new_state = state.copy()
            assert new_state.apply(action)

            assert r_rule is not None
            actions = list(
                new_state.all_applicable_actions(
                    [r_rule],
                    data.get_types().constants_mapping))
            if len(actions) != 1:
                print(actions)
                print(r_rule)
                print(new_state)
                print(
                    list(
                        new_state.all_instantiations(
                            r_rule,
                            data.get_types().constants_mapping)))
                assert len(actions) == 1
            r_state = new_state.copy()
            r_state.apply(actions[0])
            assert state == r_state
Ejemplo n.º 4
0
def test_constraints():
    # Declare some variables.
    P = Variable("P", "P")
    I = Variable("I", "I")
    bedroom = Variable("bedroom", "r")
    kitchen = Variable("kitchen", "r")
    rusty_key = Variable("rusty key", "k")
    small_key = Variable("small key", "k")
    wooden_door = Variable("wooden door", "d")
    glass_door = Variable("glass door", "d")
    chest = Variable("chest", "c")
    cabinet = Variable("cabinet", "c")
    counter = Variable("counter", "s")
    robe = Variable("robe", "o")

    # Make sure the number of basic constraints matches the number
    # of constraints in constraints.txt
    basic_constraints = [
        k for k in data.get_constraints().keys() if "-" not in k
    ]
    # assert len(basic_constraints) == 32

    # Doors can only have one state.
    door_states = ["open", "closed", "locked"]
    for door_state in door_states:
        state = State([Proposition(door_state, [wooden_door])])
        assert check_state(state)
        for door_state2 in door_states:
            if door_state == door_state2:
                continue

            state2 = state.copy()

            state2.add_fact(Proposition(door_state2, [glass_door]))  # New door
            assert check_state(state2)

            state2.add_fact(Proposition(door_state2, [wooden_door]))
            assert not check_state(state2)

    # Containers can only have one state.
    container_states = ["open", "closed", "locked"]
    for container_state in container_states:
        state = State([Proposition(container_state, [chest])])
        assert check_state(state)
        for container_state2 in container_states:
            if container_state == container_state2:
                continue

            state2 = state.copy()

            state2.add_fact(Proposition(container_state2,
                                        [cabinet]))  # New container
            assert check_state(state2)

            state2.add_fact(Proposition(container_state2, [chest]))
            assert not check_state(state2)

    # A player/supporter/container can only be at one place.
    for obj in [P, chest, counter]:
        assert check_state(State([Proposition("at", [obj, kitchen])]))
        assert check_state(State([Proposition("at", [obj, bedroom])]))
        assert not check_state(
            State([
                Proposition("at", [obj, kitchen]),
                Proposition("at", [obj, bedroom])
            ]))

    # An object is either in the player's inventory, in a container or on a supporter
    obj_locations = [
        Proposition("in", [robe, I]),
        Proposition("in", [robe, chest]),
        Proposition("on", [robe, counter])
    ]
    for obj_location in obj_locations:
        assert check_state(State([obj_location]))
        for obj_location2 in obj_locations:
            if obj_location == obj_location2: break
            assert not check_state(State([obj_location, obj_location2
                                          ])), "{}, {}".format(
                                              obj_location, obj_location2)

    # Only one key can match a container and vice-versa.
    assert check_state(State([Proposition("match", [rusty_key, chest])]))
    assert not check_state(
        State([
            Proposition("match", [small_key, chest]),
            Proposition("match", [rusty_key, chest])
        ]))
    assert not check_state(
        State([
            Proposition("match", [small_key, cabinet]),
            Proposition("match", [small_key, chest])
        ]))

    # Only one key can match a door and vice-versa.
    assert check_state(State([Proposition("match", [rusty_key, chest])]))
    assert not check_state(
        State([
            Proposition("match", [small_key, wooden_door]),
            Proposition("match", [rusty_key, wooden_door])
        ]))
    assert not check_state(
        State([
            Proposition("match", [small_key, glass_door]),
            Proposition("match", [small_key, wooden_door])
        ]))

    # A door can't be used to link more than two rooms.
    door = Variable("door", "d")
    room1 = Variable("room1", "r")
    room2 = Variable("room2", "r")
    room3 = Variable("room3", "r")
    assert not check_state(
        State([
            Proposition("link", [room1, door, room2]),
            Proposition("link", [room1, door, room3]),
        ]))

    door1 = Variable("door1", "d")
    door2 = Variable("door2", "d")
    room1 = Variable("room1", "r")
    room2 = Variable("room2", "r")
    assert not check_state(
        State([
            Proposition("link", [room1, door1, room2]),
            Proposition("link", [room1, door2, room2]),
        ]))