예제 #1
0
def test_get_reverse_action():
    kb = KnowledgeBase.default()
    for rule in kb.rules.values():
        action = maybe_instantiate_variables(rule,
                                             kb.types.constants_mapping.copy(),
                                             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(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
예제 #2
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 KnowledgeBase.default().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]),
        ]))