****************** Working with RLang ****************** There are many ways RLang can be integrated into a project. The simplest involves using a pre-existing RLang-enabled reinforcement learning agent that utilizes RLang information in a predefined manner. In this scenario, it is up to the user to provide a written RLang program which can be parsed using :py:func:`.parse` or :py:func:`.parse_file` if the program resides in a ``.rlang`` file. It is also possible to write your own RLang-enabled agent that can utilize the information stored in an RLang program (accessible via the :py:class:`.RLangKnowledge` class). This route requires a more thorough understanding of the RLang Python :py:mod:`.groundings` module. .. contents:: Using a Pre-built RLang Agent ============================= An RLang project using a pre-built agent might have the following directory structure: .. code-block:: text gridworld/ main.py \\ Python code for running the project gridworld.rlang \\ RLang program containing world information vocab.json \\ An optional (but useful) file that holds metadata and can reference additional groundings groundings.py \\ An optional file that can store RLang grounding defined in Python where ``main.py`` could be as simple as:: from simple_rl.run_experiments import run_agents_on_mdp from simple_rl.agents import QLearningAgent import rlang from rlang.agents import RLangQLearningAgent mdp, states = create_mdp() agent = QLearningAgent(mdp.get_actions()) # Create a baseline Q-Learning agent knowledge = rlang.parse_file("gridworld.rlang") # Parse RLang program into knowledge object rlang_agent = RLangQLearningAgent(mdp.get_actions(), states, knowledge) # Create RLang Q-Learning agent run_agents_on_mdp([agent, rlang_agent], mdp) # Compare performance of agents on mdp and ``gridworld.rlang`` could look like this: .. code-block:: text import "vocab.json" Constant lava_locs := [[3, 2], [1, 4], [2, 4], [2, 5]] Factor position := S[0, 1] Factor x := position[0] Factor y := position[1] Proposition reached_goal := x == 5 and y == 1 Proposition reached_wall := x == 3 and y == 1 Proposition in_lava := position in lava_locs Effect main: if in_lava: Reward -1 if reached_goal: Reward 1 if reached_wall: S' -> S For help on how to write an RLang program, see :doc:`language_reference`. Using a Vocabulary File ----------------------- While optional, vocabulary files allow for extremely powerful functionality. A minimal ``vocabulary.json`` file might contain metadata on the MDP that's being interfaced with like the size of the state and action space: .. code-block:: json { "domain": "gridworld", "mdp_metadata": { "state_space": { "size": 2, "dtype": "int" }, "action_space": { "shape": 1, "dtype": "int" } } } A more powerful vocabulary file can be used to reference additional RLang groundings declared inside an auxiliary Python file. This vocabulary file includes two :py:mod:`.feature` groundings (``angle_target`` and ``hover_target``) from an auxiliary module called ``grounding.py``: .. raw:: html
Example vocab.json with additional groundings
.. code-block:: json { "domain": "lunarlander", "mdp_metadata": { "state_space": { "size": 8, "dtype": "float" }, "action_space": { "shape": 1, "dtype": "int" } }, "modules": [ { "module_name": "grounding", "file_name": "examples/lunar_lander/grounding.py" } ], "vocabulary": { "features": [ { "name": "angle_target", "grounding": "grounding.angle_target" }, { "name": "hover_target", "grounding": "grounding.hover_target" } ] } } .. raw:: html

.. raw:: html
An accompanying grounding file grounding.py
.. code-block:: python from rlang.grounding import Feature def _angle_target(state): position = state[0:2] velocity = state[2:4] angle_targ = position[0] * 0.5 + velocity[0] * 1.0 # angle should point towards center if angle_targ > 0.4: angle_targ = 0.4 # more than 0.4 radians (22 degrees) is bad if angle_targ < -0.4: angle_targ = -0.4 return angle_targ def _hover_target(state): position = state[0:2] hover_targ = 0.55 * abs( position[0] ) return hover_targ angle_target = Feature(_angle_target) hover_target = Feature(_hover_target) .. raw:: html

``angle_target`` and ``hover_target`` can now be referenced in an RLang program like any other grounding. .. note:: It is possible to use more than one Python module to supply additional groundings Creating a Custom RLang Agent using :py:class:`.RLangKnowledge` =============================================================== To get the most out of RLang, users should implement their own RLang-enabled reinforcement learning agents. Doing so requires becoming familiar with RLang's :py:mod:`.groundings` module and most importantly the :py:class:`.RLangKnowledge` object, which holds all RLang groundings parsed from an RLang program. :py:class:`.RLangQLearningAgent` is a good example on how to integrate RLang knowledge into an RL agent: .. raw:: html
RLangQLearningAgentClass.py
.. literalinclude:: ../../rlang/rlang/agents/RLangQLearningAgentClass.py :linenos: .. raw:: html

This section should perhaps discuss the knowledge object in more detail and provide examples.