Beispiel #1
0
def _rules_to_convert_link_predicates():
    rules = [
        Rule.parse("query :: link(r, d, r') & north_of(r', r) -> north_of(d, r)"),
        Rule.parse("query :: link(r, d, r') & south_of(r', r) -> south_of(d, r)"),
        Rule.parse("query :: link(r, d, r') & west_of(r', r) -> west_of(d, r)"),
        Rule.parse("query :: link(r, d, r') & east_of(r', r) -> east_of(d, r)"),
    ]
    return rules
Beispiel #2
0
def _rules_exits():
    rules = [
        Rule.parse("query :: at(P, r) & north_of(r', r) -> north_of(r', r)"),
        Rule.parse("query :: at(P, r) & west_of(r', r) -> west_of(r', r)"),
        Rule.parse("query :: at(P, r) & south_of(r', r) -> south_of(r', r)"),
        Rule.parse("query :: at(P, r) & east_of(r', r) -> east_of(r', r)"),
    ]
    return rules
Beispiel #3
0
def _rules_predicates_inv():
    rules = [
        Rule.parse("query :: in(o, I) -> in(o, I)"),
    ]
    rules += [
        Rule.parse(
            "query :: in(f, I) & {fact}(f) -> {fact}(f)".format(fact=fact))
        for fact in FOOD_FACTS
    ]
    return rules
Beispiel #4
0
def test_match():
    rule = Rule.parse(
        "go :: at(P, r) & $link(r, d, r') & $free(r, r') & $free(r', r) -> at(P, r')"
    )

    mapping = {
        Placeholder.parse("P"): Variable.parse("P"),
        Placeholder.parse("r"): Variable.parse("r1: r"),
        Placeholder.parse("r'"): Variable.parse("r2: r"),
        Placeholder.parse("d"): Variable.parse("d"),
    }

    action = Action.parse(
        "go :: at(P, r1: r) & $link(r1: r, d, r2: r) & $free(r1: r, r2: r) & $free(r2: r, r1: r) -> at(P, r2: r)"
    )
    assert rule.match(action) == mapping

    # Order shouldn't matter

    action = Action.parse(
        "go :: $link(r1: r, d, r2: r) & $free(r1: r, r2: r) & $free(r2: r, r1: r) & at(P, r1: r) -> at(P, r2: r)"
    )
    assert rule.match(action) == mapping

    action = Action.parse(
        "go :: at(P, r1: r) & $link(r1: r, d, r2: r) & $free(r2: r, r1: r) & $free(r1: r, r2: r) -> at(P, r2: r)"
    )
    assert rule.match(action) == mapping

    # Predicate matches can't conflict
    action = Action.parse(
        "go :: at(P, r1: r) & $link(r1: r, d, r2: r) & $free(r2: r, r1: r) & $free(r1: r, r2: r) -> at(P, r3: r)"
    )
    assert rule.match(action) == None
Beispiel #5
0
def test_all_instantiations():
    state = State([
        Proposition.parse("at(P, kitchen: r)"),
        Proposition.parse("in(key: o, kitchen: r)"),
        Proposition.parse("in(egg: o, kitchen: r)"),
        Proposition.parse("in(book: o, study: r)"),
        Proposition.parse("in(book: o, study: r)"),
        Proposition.parse("in(map: o, I)"),
    ])

    take = Rule.parse("take :: $at(P, r) & in(o, r) -> in(o, I)")
    actions = set(state.all_instantiations(take))
    assert actions == {
        Action.parse("take :: $at(P, kitchen: r) & in(key: o, kitchen: r) -> in(key: o, I)"),
        Action.parse("take :: $at(P, kitchen: r) & in(egg: o, kitchen: r) -> in(egg: o, I)"),
    }

    drop = take.inverse(name="drop")
    actions = set(state.all_instantiations(drop))
    assert actions == {
        Action.parse("drop :: $at(P, kitchen: r) & in(map: o, I) -> in(map: o, kitchen: r)"),
    }

    state.apply(*actions)
    actions = set(state.all_instantiations(drop))
    assert len(actions) == 0

    # The state is no longer aware of the I variable, so there are no solutions
    actions = set(state.all_instantiations(take))
    assert len(actions) == 0
Beispiel #6
0
def test_match_complex():
    rule = Rule.parse(
        "combine/3 :: $at(P, r) & $correct_location(r) & $in(tool, I) & $in(tool', I) & $in(tool'', I) & in(o, I) & in(o', I) & in(o'', I) & $out(o''') & $used(slot) & used(slot') & used(slot'') -> in(o''', I) & free(slot') & free(slot'')"
    )

    mapping = {
        Placeholder.parse("P"): Variable.parse("P"),
        Placeholder.parse("I"): Variable.parse("I"),
        Placeholder.parse("r"): Variable.parse("r"),
        Placeholder.parse("o"): Variable.parse("o1: o"),
        Placeholder.parse("o'"): Variable.parse("o2: o"),
        Placeholder.parse("o''"): Variable.parse("o3: o"),
        Placeholder.parse("o'''"): Variable.parse("o4: o"),
        Placeholder.parse("tool"): Variable.parse("tool1: tool"),
        Placeholder.parse("tool'"): Variable.parse("tool2: tool"),
        Placeholder.parse("tool''"): Variable.parse("tool3: tool"),
        Placeholder.parse("slot"): Variable.parse("slot1: slot"),
        Placeholder.parse("slot'"): Variable.parse("slot2: slot"),
        Placeholder.parse("slot''"): Variable.parse("slot3: slot"),
    }

    action = Action.parse(
        "combine/3 :: $at(P, r) & $correct_location(r) & $in(tool1: tool, I) & $in(tool2: tool, I) & $in(tool3: tool, I) & in(o1: o, I) & in(o2: o, I) & in(o3: o, I) & $out(o4: o) & $used(slot1: slot) & used(slot2: slot) & used(slot3: slot) -> in(o4: o, I) & free(slot2: slot) & free(slot3: slot)"
    )
    for _ in range(10000):
        assert rule.match(action) == mapping
Beispiel #7
0
 def __parseRules(self, r):
     a = []
     for act in r:
         pre = self.__parsePredicates(act["precondition"])
         post = self.__parsePredicates(act["postcondition"])
         a.append(Rule(act["name"], pre, post))
     return a
Beispiel #8
0
def test_actions(state):
    take = Rule.parse(
        "take :: $at(player, world) & in(item, world) -> in(item, inventory)")
    actions = set(state.all_instantiations(take))
    """assert actions == {
        Action.parse("take :: $at(player, world) & in(apple: item, world) -> in(apple: item, inventory)")
    }"""
    print(actions)
Beispiel #9
0
def test_logic_parsing():
    P = Variable("P", "P")
    kitchen = Variable("kitchen", "r")
    egg = Variable("egg", "f")

    assert Variable.parse("P") == P
    assert Variable.parse("kitchen: r") == kitchen

    at_kitchen = Proposition("at", [P, kitchen])
    in_kitchen = Proposition("in", [egg, kitchen])
    raw_egg = Proposition("raw", [egg])
    cooked_egg = Proposition("cooked", [egg])

    assert Proposition.parse("at(P, kitchen: r)") == at_kitchen

    assert Signature.parse("at(P, r)") == at_kitchen.signature

    cook_egg = Action("cook", [at_kitchen, in_kitchen, raw_egg],
                      [at_kitchen, in_kitchen, cooked_egg])
    assert Action.parse(
        "cook :: $at(P, kitchen: r) & $in(egg: f, kitchen: r) & raw(egg: f) -> cooked(egg: f)"
    ) == cook_egg

    P = Placeholder("P", "P")
    r = Placeholder("r", "r")
    d = Placeholder("d", "d")
    rp = Placeholder("r'", "r")
    assert Placeholder.parse("P") == P
    assert Placeholder.parse("r") == r
    assert Placeholder.parse("d") == d
    assert Placeholder.parse("r'") == rp

    at_r = Predicate("at", [P, r])
    link = Predicate("link", [r, d, rp])
    unlocked = Predicate("unlocked", [d])
    at_rp = Predicate("at", [P, rp])
    assert Predicate.parse("link(r, d, r')") == link

    go = Rule("go", [at_r, link, unlocked], [link, unlocked, at_rp])
    assert Rule.parse(
        "go :: at(P, r) & $link(r, d, r') & $unlocked(d) -> at(P, r')") == go

    # Make sure the types match in the whole expression
    assert_raises(ValueError, Rule.parse,
                  "take :: $at(P, r) & $in(c, r) & in(o: k, c) -> in(o, I)")
Beispiel #10
0
def _rules_predicates_recipe():
    rules = [
        Rule.parse(
            "query :: in(ingredient, RECIPE) & base(f, ingredient) -> part_of(f, RECIPE)"
        ),
        Rule.parse(
            "query :: in(ingredient, RECIPE) & base(f, ingredient) & roasted(ingredient) -> needs_roasted(f)"
        ),
        Rule.parse(
            "query :: in(ingredient, RECIPE) & base(f, ingredient) & grilled(ingredient) -> needs_grilled(f)"
        ),
        Rule.parse(
            "query :: in(ingredient, RECIPE) & base(f, ingredient) & fried(ingredient) -> needs_fried(f)"
        ),
        Rule.parse(
            "query :: in(ingredient, RECIPE) & base(f, ingredient) & sliced(ingredient) -> needs_sliced(f)"
        ),
        Rule.parse(
            "query :: in(ingredient, RECIPE) & base(f, ingredient) & chopped(ingredient) -> needs_chopped(f)"
        ),
        Rule.parse(
            "query :: in(ingredient, RECIPE) & base(f, ingredient) & diced(ingredient) -> needs_diced(f)"
        ),
    ]
    return rules
Beispiel #11
0
def test_rules():
    # Make sure the number of basic rules matches the number
    # of rules in rules.txt
    basic_rules = [k for k in data.get_rules().keys() if "-" not in k]
    assert len(basic_rules) == 19

    for rule in data.get_rules().values():
        infos = rule.serialize()
        loaded_rule = Rule.deserialize(infos)
        assert loaded_rule == rule
Beispiel #12
0
    def deserialize(cls, data: Mapping) -> "Game":
        """ Creates a `Game` from serialized data.

        Args:
            data: Serialized data with the needed information to build a
                  `Game` object.
        """
        world = World.deserialize(data["world"])
        grammar = None
        if "grammar" in data:
            grammar = Grammar(data["grammar"])
        quests = [Quest.deserialize(d) for d in data["quests"]]
        game = cls(world, grammar, quests)
        game._infos = {k: EntityInfo.deserialize(v) for k, v in data["infos"]}
        game.state = State.deserialize(data["state"])
        game._rules = {k: Rule.deserialize(v) for k, v in data["rules"]}
        game._types = VariableTypeTree.deserialize(data["types"])
        game.metadata = data.get("metadata", {})

        return game
Beispiel #13
0
def test_rules():
    for rule in KnowledgeBase.default().rules.values():
        infos = rule.serialize()
        loaded_rule = Rule.deserialize(infos)
        assert loaded_rule == rule
Beispiel #14
0
def _rules_predicates_scope():
    rules = [
        Rule.parse("query :: at(P, r) -> at(P, r)"),
        Rule.parse("query :: at(P, r) & at(o, r) -> at(o, r)"),
        Rule.parse("query :: at(P, r) & at(d, r) -> at(d, r)"),
        Rule.parse("query :: at(P, r) & at(s, r) -> at(s, r)"),
        Rule.parse("query :: at(P, r) & at(c, r) -> at(c, r)"),
        Rule.parse("query :: at(P, r) & at(s, r) & on(o, s) -> on(o, s)"),
        Rule.parse("query :: at(P, r) & at(c, r) & open(c) -> open(c)"),
        Rule.parse("query :: at(P, r) & at(c, r) & closed(c) -> closed(c)"),
        Rule.parse("query :: at(P, r) & at(c, r) & open(c) & in(o, c) -> in(o, c)"),
        Rule.parse("query :: at(P, r) & link(r, d, r') & open(d) -> open(d)"),
        Rule.parse("query :: at(P, r) & link(r, d, r') & closed(d) -> closed(d)"),
        Rule.parse("query :: at(P, r) & link(r, d, r') & north_of(r', r) -> north_of(d, r)"),
        Rule.parse("query :: at(P, r) & link(r, d, r') & south_of(r', r) -> south_of(d, r)"),
        Rule.parse("query :: at(P, r) & link(r, d, r') & west_of(r', r) -> west_of(d, r)"),
        Rule.parse("query :: at(P, r) & link(r, d, r') & east_of(r', r) -> east_of(d, r)"),
    ]
    rules += [Rule.parse("query :: at(P, r) & at(f, r) & {fact}(f) -> {fact}(f)".format(fact=fact)) for fact in FOOD_FACTS]
    rules += [Rule.parse("query :: at(P, r) & at(s, r) & on(f, s) & {fact}(f) -> {fact}(f)".format(fact=fact)) for fact in FOOD_FACTS]
    rules += [Rule.parse("query :: at(P, r) & at(c, r) & open(c) & in(f, c) & {fact}(f) -> {fact}(f)".format(fact=fact)) for fact in FOOD_FACTS]
    return rules