def test_packable(): test_stuff = cls._pack_.__doc__.split("```") tinst = eval(utils.dedent(test_stuff[1])) tobj = eval(utils.dedent(test_stuff[2])) uinst = unpack(tobj, cls) pobj = pack(tinst) urec = unpack(pobj, cls) prec = pack(uinst) assert tinst == uinst, ( ( "Unpacked object doesn't match eval'd version:\n```\n{}\n```\n{}\n```" "\nDifferences:\n {}" ).format(str(tinst), str(uinst), "\n ".join(diff(tinst, uinst))) ) assert pobj == tobj, ( ( "Packed object doesn't match given:\n```\n{}\n```\n{}\n```" "\nDifferences:\n {}" ).format( str(tobj), str(pobj), "\n ".join(diff(tobj, pobj)) ) ) assert tinst == urec, ( ( "Pack/unpacked object doesn't match:\n```\n{}\n```\n{}\n```" "\nDifferences:\n {}" ).format( str(tinst), str(urec), "\n ".join(diff(tinst, urec)) ) ) assert tobj == prec, ( ( "Unpack/packed object doesn't match:\n```\n{}\n```\n{}\n```" "\nDifferences:\n {}" ).format( str(tobj), str(prec), "\n ".join(diff(tobj, prec)) ) ) return True
def _pack_(self): """ Returns a simple representation of this option suitable for direct conversion to JSON. Example: ``` Option( "leave_it", [ Outcome( "dies", { "befriend_dragon": "awful", "kill_dragon": "great" }, "hinted", "unlikely", "even" ), Outcome( "dislikes_abandonment", { "befriend_dragon": "bad" }, "explicit", 0.97 ) ] ) ``` { "name": "leave_it", "outcomes": [ { "actual_likelihood": "even", "apparent_likelihood": "unlikely", "effects": { "befriend_dragon": "awful", "kill_dragon": "great" }, "name": "dies", "salience": "hinted" }, { "apparent_likelihood": 0.97, "effects": { "befriend_dragon": "bad" }, "name": "dislikes_abandonment", "salience": "explicit" }, ] } ``` """ return { "name": self.name, "outcomes": [ pack(self.outcomes[k]) for k in sorted(list(self.outcomes.keys())) ] }
def package(story): with open("story_engine.js", 'r') as fin: ejs = fin.read() return TEMPLATE.format(title=story.name.title(), story_content=pack(story), engine=ejs)
def _pack_(self): """ Packs into a simple object; suitable for conversion to JSON. Example: ``` Prospective( "avoid_conflict", "run_or_fight", "run", "get_away", 0.8, "explicit", certainty="even" ) ``` { "type": "Prospective", "goal": "avoid_conflict", "choice": "run_or_fight", "option": "run", "outcome": "get_away", "valence": 0.8, "salience": "explicit", "certainty": "even" } ``` """ result = super()._pack_() result["type"] = "Prospective" result["certainty"] = pack(self.certainty) return result
def _pack_(self): """ Returns a simple representation of this object, suitable for conversion to JSON. Example: ``` ModeOfEngagement( "friendly_but_cautious", [ "befriend_dragon", "health_and_safety" ], { "befriend_dragon": 2, "health_and_safety": 1 } ) ``` { "name": "friendly_but_cautious", "goals": [ { "name": "befriend_dragon", "type": "PlayerGoal" }, { "name": "health_and_safety", "type": "PlayerGoal" } ], "priorities": { "befriend_dragon": 2, "health_and_safety": 1 } } ``` """ return { "name": self.name, "goals": [pack(g) for g in self.goals.values()], "priorities": self.priorities }
def save_new_story(self, story, force=False, is_module=False): """ Saves a new story to the database. Returns True if it succeeds, or False (and prints a warning message) if a story by that title already exists. Always returns true and replaces any existing story if 'force' is True. Saves the story as a module if is_module is True. """ table = "modules" if is_module else "stories" cur = self.connection.cursor() title = story.title.title() author = story.author.title() cur.execute( "SELECT * FROM {} WHERE title = ? AND author = ?;".format(table), (title, author)) if len(cur.fetchall()) > 0: if force: self.update_story(story) else: print(("Warning: attempted to save new {} by '{}' " "with duplicate title '{}'.").format( "module" if is_module else "story", author, title), file=sys.stderr) return False # TODO: maximize packing efficiency cur.execute( "INSERT INTO {}(title, author, package) values(?, ?, ?);".format( table), (title, author, json.dumps(pack(story)))) self.connection.commit() return True
def update_story(self, story, is_module=False): """ Updates a story (or module) in the database, overwriting the current contents. """ table = "modules" if is_module else "stories" cur = self.connection.cursor() # TODO: maximize packing efficiency cur.execute( "UPDATE {} SET package = ? WHERE title = ? AND author = ?;".format( table), (json.dumps( pack(story)), story.title.title(), story.author.title())) # TODO: Error handling here self.connection.commit()
def test_types(): c = Certainty(0.78) assert Certainty.abstract(c) == Certainty.likely assert Certainty.abstract(c) == Certainty("likely") c = Certainty("impossible") assert c == 0.0 assert type(c + 0.1) == Certainty assert str(c) == "Certainty(0.0)" assert pack(c) == "impossible" return True
def _pack_(self): """ Returns a simple object suitable for conversion to JSON. Example: ``` Percept( "avoid_conflict", "run_or_fight", "run", None, 0.8, 1.0 ) ``` { "type": "Percept", "goal": "avoid_conflict", "choice": "run_or_fight", "option": "run", "outcome": None, "valence": 0.8, "salience": "explicit" } ``` """ return { "type": "Percept", "goal": self.goal, "choice": self.choice, "option": self.option, "outcome": self.outcome, "valence": pack(self.valence), "salience": pack(self.salience) }
def _pack_(self): """ Returns a simple representation of this option suitable for direct conversion to JSON. Example: ``` Outcome( "dies", { "befriend_dragon": "awful", "kill_dragon": "great" }, "hinted", "unlikely", "even" ) ``` { "actual_likelihood": "even", "apparent_likelihood": "unlikely", "effects": { "befriend_dragon": "awful", "kill_dragon": "great" }, "name": "dies", "salience": "hinted" } ``` """ if self.apparent_likelihood == self.actual_likelihood: return { "name": self.name, "salience": pack(self.salience), "apparent_likelihood": pack(self.apparent_likelihood), "effects": {g: pack(self.goal_effects[g]) for g in self.goal_effects} } else: return { "name": self.name, "salience": pack(self.salience), "apparent_likelihood": pack(self.apparent_likelihood), "actual_likelihood": pack(self.actual_likelihood), "effects": {g: pack(self.goal_effects[g]) for g in self.goal_effects} }
def _pack_(self): """ Packs into a simple object; suitable for conversion to JSON. Example: ``` Retrospective( "avoid_conflict", "run_or_fight", "run", "get_caught", -0.95, 1.0, expected_valence="awful", expected_certainty=0.5, expected_salience=1.0 ) ``` { "type": "Retrospective", "goal": "avoid_conflict", "choice": "run_or_fight", "option": "run", "outcome": "get_caught", "valence": "awful", "salience": "explicit", "prospective": { "type": "Prospective", "goal": "avoid_conflict", "choice": "run_or_fight", "option": "run", "outcome": "get_caught", "valence": "awful", "salience": "explicit", "certainty": "even" } } ``` """ result = super()._pack_() result["type"] = "Retrospective" result["prospective"] = pack(self.prospective) return result
def _pack_(self): """ Returns a simple representation of this choice, suitable for direct conversion to JSON. Example: ``` Choice( "Rescue the baby dragon or not?", [ Option( "rescue_it", [ Outcome( "bites_your_hand", { "health_and_safety": Valence("unsatisfactory"), "befriend_dragon": Valence("unsatisfactory"), }, Salience("implicit"), Certainty("even"), ), Outcome( "appreciates_kindness", { "befriend_dragon": "good" }, "explicit", "likely", ) ] ), Option( "leave_it", [ Outcome( "dislikes_abandonment", { "befriend_dragon": "bad" }, "explicit", 0.97, ), Outcome( "dies", { "befriend_dragon": "awful", "kill_dragon": "great" }, "hinted", "unlikely", actual_likelihood="even" ) ] ) ] ) ``` { "name": "Rescue the baby dragon or not?", "options": { "leave_it": { "name": "leave_it", "outcomes": [ { "actual_likelihood": "even", "apparent_likelihood": "unlikely", "effects": { "befriend_dragon": "awful", "kill_dragon": "great" }, "name": "dies", "salience": "hinted" }, { "apparent_likelihood": 0.97, "effects": { "befriend_dragon": "bad" }, "name": "dislikes_abandonment", "salience": "explicit" }, ] }, "rescue_it": { "name": "rescue_it", "outcomes": [ { "apparent_likelihood": "likely", "effects": { "befriend_dragon": "good" }, "name": "appreciates_kindness", "salience": "explicit" }, { "apparent_likelihood": "even", "effects": { "befriend_dragon": "unsatisfactory", "health_and_safety": "unsatisfactory" }, "name": "bites_your_hand", "salience": "implicit" } ] } } } ``` """ return {"name": self.name, "options": pack(self.options)}
def _pack_(self): """ Packs this Decision into a simple object representation which can be converted to JSON. Example: ``` Decision( Choice( "Rescue the baby dragon or not?", [ Option( "rescue_it", [ Outcome( "bites_your_hand", { "health_and_safety": Valence("unsatisfactory"), "befriend_dragon": Valence("unsatisfactory"), }, Salience("implicit"), Certainty("even"), ), Outcome( "appreciates_kindness", { "befriend_dragon": "good" }, "explicit", "likely", ) ] ), Option( "leave_it", [ Outcome( "dislikes_abandonment", { "befriend_dragon": "bad" }, "explicit", 0.97, ), Outcome( "dies", { "befriend_dragon": "awful", "kill_dragon": "great" }, "hinted", "unlikely", actual_likelihood="even" ) ] ) ] ), Option( "rescue_it", [ Outcome( "bites_your_hand", { "health_and_safety": Valence("unsatisfactory"), "befriend_dragon": Valence("unsatisfactory"), }, Salience("implicit"), Certainty("even"), ), Outcome( "appreciates_kindness", { "befriend_dragon": "good" }, "explicit", "likely", ) ] ), [ Outcome( "appreciates_kindness", { "befriend_dragon": "good" }, "explicit", "likely", ) ], prospective_impressions=None, factored_decision_models=None, goal_relevance=None, retrospective_impressions=None ) ``` { "choice": { "name": "Rescue the baby dragon or not?", "options": { "leave_it": { "name": "leave_it", "outcomes": [ { "actual_likelihood": "even", "apparent_likelihood": "unlikely", "effects": { "befriend_dragon": "awful", "kill_dragon": "great" }, "name": "dies", "salience": "hinted" }, { "apparent_likelihood": 0.97, "effects": { "befriend_dragon": "bad" }, "name": "dislikes_abandonment", "salience": "explicit" }, ] }, "rescue_it": { "name": "rescue_it", "outcomes": [ { "apparent_likelihood": "likely", "effects": { "befriend_dragon": "good" }, "name": "appreciates_kindness", "salience": "explicit" }, { "apparent_likelihood": "even", "effects": { "befriend_dragon": "unsatisfactory", "health_and_safety": "unsatisfactory" }, "name": "bites_your_hand", "salience": "implicit" } ] } } }, "option": { "name": "rescue_it", "outcomes": [ { "apparent_likelihood": "likely", "effects": { "befriend_dragon": "good" }, "name": "appreciates_kindness", "salience": "explicit" }, { "apparent_likelihood": "even", "effects": { "befriend_dragon": "unsatisfactory", "health_and_safety": "unsatisfactory" }, "name": "bites_your_hand", "salience": "implicit" } ] }, "outcomes": [ { "apparent_likelihood": "likely", "effects": { "befriend_dragon": "good" }, "name": "appreciates_kindness", "salience": "explicit" } ], "prospective_impressions": None, "factored_decision_models": None, "goal_relevance": None, "retrospective_impressions": None, } ``` TODO: More examples! """ return { "choice": pack(self.choice), "option": pack(self.option), "outcomes": [ pack(o) for o in self.outcomes.values() ], "prospective_impressions": pack(self.prospective_impressions), "factored_decision_models": pack(self.factored_decision_models), "goal_relevance": pack(self.goal_relevance), "retrospective_impressions": pack(self.retrospective_impressions), # Note: no need to pack simplified retrospective impressions, as they'll # be reconstructed from the full retrospectives. }
def __str__(self): # TODO: Better here return str(pack(self))
def _pack_(self): return "set {} {}".format('.'.join(self.keys), json.dumps(pack(self.value), indent=None))
def _pack_(self): """ Returns a simplified version suitable for json.dumps. See packable.py. Example: ``` Story( "The Ocean Calls", "Anonymous", "at_the_beach", { "at_the_beach": StoryNode( "at_the_beach", ( "You walk along the beach, watching seabirds dance with the waves. " "The sea calls to you, but you should go home." ), { "The sea": [ "wading_out", "(set: mood : desolate)" ], "go home": [ "back_home", "(set: mood : warm)" ] } ), "wading_out": StoryNode( "wading_out", "You wade out into the icy water, shivering with anticipation." ), "back_home": StoryNode( "back_home", "You step into the warmth of your living room and lock the door." ) } ) ``` { "title": "The Ocean Calls", "author": "Anonymous", "start": "at_the_beach", "nodes": { "at_the_beach": { "name": "at_the_beach", "content": "You walk along the beach, watching seabirds dance with the waves. The sea calls to you, but you should go home.", "successors": { "The sea": [ "wading_out", "(set: mood : desolate)" ], "go home": [ "back_home", "(set: mood : warm)" ] } }, "wading_out": { "name": "wading_out", "content": "You wade out into the icy water, shivering with anticipation." }, "back_home": { "name": "back_home", "content": "You step into the warmth of your living room and lock the door." }, } } ``` """ result = { "title": self.title, "author": self.author, "start": self.start, "nodes": pack(self.nodes) } if self.modules: result["modules"] = self.modules if self.setup: result["setup"] = self.setup return result
def __str__(self): return str(pack(self))
def _pack_(self): """ Returns a simple representation of this option suitable for direct conversion to JSON. Example: (Note that this example's use of mode/goal rankings/adjustments is a bit silly as the mode rankings are enough to affectively achieve the desired priorities alone.) ``` PlayerModel( "aggressive", DecisionMethod.utilizing, { "defensive": ModeOfEngagement( "defensive", [ "attack", "defend" ], { "attack": 3, "defend": 2 } ), "aggressive": ModeOfEngagement( "aggressive", [ "attack", "defend" ], { "attack": 2, "defend": 3 } ) }, SoftPriority(0.6), mode_ranking={ "defensive": 2, "aggressive": 1 }, mode_adjustments={ "defensive": 1 }, goal_adjustments={ "defend": 1 }, goal_overrides={ "attack": 1 } ) ``` { "name": "aggressive", "decision_method": "utilizing", "modes": { "defensive": { "name": "defensive", "goals": [ { "name": "attack", "type": "PlayerGoal" }, { "name": "defend", "type": "PlayerGoal" } ], "priorities": { "attack": 3, "defend": 2 } }, "aggressive": { "name": "aggressive", "goals": [ { "name": "attack", "type": "PlayerGoal" }, { "name": "defend", "type": "PlayerGoal" } ], "priorities": { "attack": 2, "defend": 3 } } }, "priority_method": [ "softpriority", 0.6 ], "mode_ranking": { "defensive": 2, "aggressive": 1 }, "mode_adjustments": { "defensive": 1 }, "goal_adjustments": { "defend": 1 }, "goal_overrides": { "attack": 1 } } ``` """ result = { "name": self.name, "decision_method": pack(self.decision_method), "modes": {key: pack(val) for (key, val) in self.modes.items()} } if self.priority_method != engagement.PriorityMethod.softpriority: result["priority_method"] = pack(self.priority_method) nondefault_mode_rankings = { mn: self.mode_ranking[mn] for mn in self.mode_ranking if self.mode_ranking[mn] != engagement.DEFAULT_PRIORITY } if nondefault_mode_rankings: result["mode_ranking"] = nondefault_mode_rankings nonzero_adjustments = { mn: self.mode_adjustments[mn] for mn in self.mode_adjustments if self.mode_adjustments[mn] != 0 } if nonzero_adjustments: result["mode_adjustments"] = nonzero_adjustments nonzero_adjustments = { gn: self.goal_adjustments[gn] for gn in self.goal_adjustments if self.goal_adjustments[gn] != 0 } if nonzero_adjustments: result["goal_adjustments"] = nonzero_adjustments if self.goal_overrides: result["goal_overrides"] = self.goal_overrides return result