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
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]), ]))