def get_human_readable_action(self, action: Action) -> Action: precondition = list( map(self.get_human_readable_fact, action.preconditions)) postconditions = list( map(self.get_human_readable_fact, action.postconditions)) name = self.kb.inform7_commands[action.name].split("{")[0].strip() return Action(name, precondition, postconditions)
def set_conditions(self, conditions: Iterable[Proposition]) -> Action: """ Set the triggering conditions for this event. Args: conditions: Set of propositions which need to be all true in order for this event to get triggered. Returns: Action that can only be applied when all conditions are statisfied. """ if not conditions: if len(self.actions) == 0: raise UnderspecifiedEventError() # The default winning conditions are the postconditions of the # last action in the quest. conditions = self.actions[-1].postconditions variables = sorted(set([v for c in conditions for v in c.arguments])) event = Proposition("event", arguments=variables) self.condition = Action("trigger", preconditions=conditions, postconditions=list(conditions) + [event]) return self.condition
def set_winning_conditions( self, winning_conditions: Optional[Collection[Proposition]]) -> Action: """ Sets wining conditions for this quest. Args: winning_conditions: Set of propositions that need to be true before marking the quest as completed. Default: postconditions of the last action. Returns: An action that is only applicable when the quest is finished. """ if winning_conditions is None: if len(self.actions) == 0: raise UnderspecifiedQuestError() # The default winning conditions are the postconditions of the # last action in the quest. winning_conditions = self.actions[-1].postconditions # TODO: Make win propositions distinguishable by adding arguments? win_fact = Proposition("win") self.win_action = Action("win", preconditions=winning_conditions, postconditions=list(winning_conditions) + [win_fact]) return self.win_action
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)")
def set_failing_conditions(self, failing_conditions: Optional[Collection[Proposition]]) -> Optional[Action]: """ Sets the failing conditions of this quest. Args: failing_conditions: Set of propositions that if are all true means the quest is failed. Default: can't fail the quest. Returns: An action that is only applicable when the quest has failed or `None` if the quest can be failed. """ self.fail_action = None if failing_conditions is not None: # TODO: Make fail propositions distinguishable by adding arguments? fail_fact = Proposition("fail") self.fail_action = Action("fail", preconditions=failing_conditions, postconditions=list(failing_conditions) + [fail_fact]) return self.fail_action
def set_failing_conditions( self, failing_conditions: Optional[Collection[Proposition]] ) -> Optional[Action]: """ Sets the failing conditions of this quest. Args: failing_conditions: Set of propositions that if are all true means the quest is failed. Default: can't fail the quest. Returns: An action that is only applicable when the quest has failed or `None` if the quest can be failed. """ self.fail_action = None if failing_conditions is not None: self.fail_action = Action("fail", failing_conditions, [Proposition("fail")]) return self.fail_action
def set_winning_conditions( self, winning_conditions: Optional[Collection[Proposition]]) -> Action: """ Sets wining conditions for this quest. Args: winning_conditions: Set of propositions that need to be true before marking the quest as completed. Default: postconditions of the last action. Returns: An action that is only applicable when the quest is finished. """ if winning_conditions is None: if self.actions is None: raise UnderspecifiedQuestError() # The default winning conditions are the postconditions of the # last action in the quest. winning_conditions = self.actions[-1].postconditions self.win_action = Action("win", winning_conditions, [Proposition("win")]) return self.win_action
from typing import List from textworld.logic import Action, Proposition, State from textworld.generator.user_query import query_for_important_facts # noinspection PyAbstractClass class FakeState(State): def __init__(self, parrot_facts: List[Proposition]): super().__init__() self._facts = parrot_facts @property def facts(self): return self._facts # generate fake propositions propositions = [] for i in range(3): new_prop = Proposition(name='thing %d' % (i, )) propositions.append(new_prop) fake_state = FakeState(propositions) # run the test action = Action(name='Test action', preconditions=[], postconditions=propositions) facts = query_for_important_facts(actions=[action], last_game_state=fake_state) print(facts)