{ "cells": [ { "cell_type": "markdown", "id": "eb9fb4a1a68e633", "metadata": {}, "source": [ "# Tutorial AAAI 2026" ] }, { "cell_type": "markdown", "id": "1ac309b575ed4764", "metadata": {}, "source": [ "AMLGym provides several benchmark domains from previous Internaional Planning Competitions (IPCs)." ] }, { "cell_type": "code", "execution_count": null, "id": "9bb5ad965be80b96", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T14:06:08.177367Z", "start_time": "2026-01-19T14:06:06.758340Z" } }, "outputs": [], "source": [ "!pip install amlgym > /dev/null 2>&1" ] }, { "cell_type": "code", "execution_count": null, "id": "initial_id", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T08:47:19.567245Z", "start_time": "2026-01-19T08:47:19.560728Z" } }, "outputs": [], "source": [ "from amlgym.benchmarks import print_domains\n", "\n", "print_domains()" ] }, { "cell_type": "markdown", "id": "bf47f050c2091de8", "metadata": {}, "source": [ "The PDDL model of each domain can be inspected:" ] }, { "cell_type": "code", "execution_count": null, "id": "fd36b0d1fc890673", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T08:47:22.280376Z", "start_time": "2026-01-19T08:47:22.276892Z" } }, "outputs": [], "source": [ "from amlgym.benchmarks import get_domain_path\n", "\n", "domain_path = get_domain_path('blocksworld')\n", "print(domain_path)" ] }, { "cell_type": "code", "execution_count": null, "id": "9f69a6f17bb858d8", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T08:47:23.926085Z", "start_time": "2026-01-19T08:47:23.922732Z" } }, "outputs": [], "source": [ "from amlgym.benchmarks import get_domain\n", "\n", "domain_pddl = get_domain('blocksworld')\n", "print(domain_pddl)" ] }, { "cell_type": "markdown", "id": "a1140b080ac0052c", "metadata": {}, "source": [ "A set of 10 trajectories is provided for each domain:" ] }, { "cell_type": "code", "execution_count": null, "id": "2248b833a8b45659", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T08:47:29.441556Z", "start_time": "2026-01-19T08:47:29.435264Z" } }, "outputs": [], "source": [ "from amlgym.benchmarks import get_trajectories_path\n", "from pprint import pprint\n", "\n", "trajectory_paths = get_trajectories_path('blocksworld')\n", "pprint(trajectory_paths)" ] }, { "cell_type": "markdown", "id": "a9308a44e4025670", "metadata": {}, "source": [ "An example of trajectory for the `blocksworld` domain is:" ] }, { "cell_type": "code", "execution_count": null, "id": "e5bdac6da94e245d", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T08:47:34.386507Z", "start_time": "2026-01-19T08:47:34.380704Z" } }, "outputs": [], "source": [ "from amlgym.benchmarks import get_trajectories\n", "\n", "trajectory_idx = 0\n", "trajectory = get_trajectories('blocksworld')[trajectory_idx]\n", "print(trajectory)" ] }, { "cell_type": "raw", "id": "fc68d4ccab3a98b3", "metadata": {}, "source": [ "The problem used for generating the trajectory can be obtained by:" ] }, { "cell_type": "code", "execution_count": null, "id": "5e42c531f4094aa", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T08:50:08.231726Z", "start_time": "2026-01-19T08:50:08.226442Z" } }, "outputs": [], "source": [ "from amlgym.benchmarks import get_problems_path\n", "\n", "problem_path = get_problems_path('blocksworld')[trajectory_idx]\n", "print(problem_path)" ] }, { "cell_type": "code", "execution_count": null, "id": "7bb6c8d57b7bf935", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T08:50:18.755776Z", "start_time": "2026-01-19T08:50:18.752924Z" } }, "outputs": [], "source": [ "with open(problem_path, 'r') as f:\n", " print(f.read())" ] }, { "cell_type": "markdown", "id": "80d1b88748df61ad", "metadata": {}, "source": [ "## Passive Algorithms" ] }, { "cell_type": "markdown", "id": "9ac175afe650249f", "metadata": {}, "source": [ "AMLGym includes several algorithms for passive learning domain models from full/partial/noisy trajectories." ] }, { "cell_type": "code", "execution_count": null, "id": "fe7fa775676f69e7", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T08:51:32.840730Z", "start_time": "2026-01-19T08:51:29.342303Z" } }, "outputs": [], "source": [ "from amlgym.algorithms import print_algorithms\n", "\n", "print_algorithms()" ] }, { "cell_type": "markdown", "id": "e6765055c8a63d35", "metadata": {}, "source": [ "### Passive learning with full observability" ] }, { "cell_type": "markdown", "id": "5aa808127d97a0aa", "metadata": {}, "source": [ "Instantiate an algorithm for passive learning domain models in fully observable environments (e.g., [SAM](https://proceedings.kr.org/2021/36/)):" ] }, { "cell_type": "code", "execution_count": null, "id": "a41e20826318a782", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T08:56:28.569991Z", "start_time": "2026-01-19T08:56:28.565182Z" } }, "outputs": [], "source": [ "from amlgym.algorithms import get_algorithm\n", "\n", "learner = get_algorithm('sam')" ] }, { "cell_type": "markdown", "id": "b1037c13855c660e", "metadata": {}, "source": [ "Get an empty IPC domain:" ] }, { "cell_type": "code", "execution_count": null, "id": "a99c933d94d01d00", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T08:56:37.649738Z", "start_time": "2026-01-19T08:56:37.495607Z" } }, "outputs": [], "source": [ "from amlgym.util.util import empty_domain\n", "\n", "domain_path = get_domain_path('blocksworld')\n", "\n", "domain_empty_path = empty_domain(domain_path)\n", "with open(domain_empty_path, 'r') as f:\n", " print(f.read())" ] }, { "cell_type": "markdown", "id": "ba076d560eb96056", "metadata": {}, "source": [ "Get a set of trajectories associated with the domain:" ] }, { "cell_type": "code", "execution_count": null, "id": "9e8ba83a6cd89a6c", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T08:57:34.573166Z", "start_time": "2026-01-19T08:57:34.569111Z" } }, "outputs": [], "source": [ "traj_paths = get_trajectories_path('blocksworld')" ] }, { "cell_type": "markdown", "id": "f7c9ddcdd8b5c4bd", "metadata": {}, "source": [ "Learn a domain model specified in PDDL:" ] }, { "cell_type": "code", "execution_count": null, "id": "a8dd91c9f6b33c9", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T08:57:39.535753Z", "start_time": "2026-01-19T08:57:39.464850Z" } }, "outputs": [], "source": [ "model = learner.learn(domain_empty_path, traj_paths)\n", "print(model)" ] }, { "cell_type": "markdown", "id": "ba8a6d10b270e5e5", "metadata": {}, "source": [ "Save the learned model to a file" ] }, { "cell_type": "code", "execution_count": null, "id": "bfe618e6c595c95c", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T10:03:05.603379Z", "start_time": "2026-01-19T10:03:05.600336Z" } }, "outputs": [], "source": [ "domain_learned_path = 'domain_learned.pddl'\n", "with open(domain_learned_path, 'w') as f:\n", " f.write(model)" ] }, { "cell_type": "markdown", "id": "22c327014bb9a7a", "metadata": {}, "source": [ "## Evaluating a domain model" ] }, { "cell_type": "markdown", "id": "edc3c77f83382608", "metadata": {}, "source": [ "AMLGym provides several measures for evaluation an action model w.r.t. a reference model or simulator." ] }, { "cell_type": "markdown", "id": "ec7aed30828b4ef0", "metadata": {}, "source": [ "### Syntactic Similarity" ] }, { "cell_type": "markdown", "id": "663de3d2b7129332", "metadata": {}, "source": [ "[Syntactic similarity](https://amlgym.readthedocs.io/en/latest/metrics/syntactic.html) can be measured by means of precision and recall:" ] }, { "cell_type": "code", "execution_count": null, "id": "637f44d49e748a27", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T10:03:09.961801Z", "start_time": "2026-01-19T10:03:09.929788Z" } }, "outputs": [], "source": [ "from amlgym.metrics import syntactic_precision\n", "from pprint import pprint\n", "\n", "domain_ref_path = get_domain_path('blocksworld')\n", "precision = syntactic_precision(domain_learned_path, domain_ref_path)\n", "pprint(precision)" ] }, { "cell_type": "code", "execution_count": null, "id": "c90516c3f71cf6be", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T10:03:29.839448Z", "start_time": "2026-01-19T10:03:29.814863Z" } }, "outputs": [], "source": [ "from amlgym.metrics import syntactic_recall\n", "\n", "recall = syntactic_recall(domain_learned_path, domain_ref_path)\n", "pprint(recall)" ] }, { "cell_type": "markdown", "id": "4483500d62c03de3", "metadata": {}, "source": [ "### Problem solving" ] }, { "cell_type": "markdown", "id": "4c6846a8d23e5e2", "metadata": {}, "source": [ "Get the set of problems necessary to evaluate [problem solving](https://amlgym.readthedocs.io/en/latest/metrics/solving.html) metrics:" ] }, { "cell_type": "code", "execution_count": null, "id": "77137504f589c228", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T10:05:54.095958Z", "start_time": "2026-01-19T10:05:54.089401Z" } }, "outputs": [], "source": [ "probs_paths = get_problems_path('blocksworld', kind='solving')\n", "pprint(probs_paths)" ] }, { "cell_type": "markdown", "id": "e1ce941e0a92ce4a", "metadata": {}, "source": [ "Solve the problems with the model to be evaluated and evaluate it in a simulator defined by a reference model:" ] }, { "cell_type": "code", "execution_count": null, "id": "4e119069be726c39", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T10:06:13.408270Z", "start_time": "2026-01-19T10:06:09.429748Z" } }, "outputs": [], "source": [ "from amlgym.metrics import problem_solving\n", "import unified_planning\n", "unified_planning.shortcuts.get_environment().credits_stream = None\n", "\n", "metrics = problem_solving(domain_learned_path, domain_ref_path, probs_paths, timeout=60)\n", "pprint(metrics)" ] }, { "cell_type": "markdown", "id": "70cd0c1944c83fe4", "metadata": {}, "source": [ "### Predictive power" ] }, { "cell_type": "markdown", "id": "5a28745fed48d215", "metadata": {}, "source": [ "Get the test set of states necessary to evaluate [predicted applicability and predicted effects](https://amlgym.readthedocs.io/en/latest/metrics/predictive.html) metrics:" ] }, { "cell_type": "code", "execution_count": null, "id": "e6e398e152bb6a76", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T10:23:13.258873Z", "start_time": "2026-01-19T10:23:13.253931Z" } }, "outputs": [], "source": [ "from amlgym.benchmarks import get_test_states\n", "\n", "test_states = get_test_states('blocksworld')\n", "print(len(test_states.keys()))\n", "pprint(next(iter(test_states.keys())))" ] }, { "cell_type": "code", "execution_count": null, "id": "ad28f33d9911677e", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T10:23:13.691036Z", "start_time": "2026-01-19T10:23:13.687057Z" } }, "outputs": [], "source": [ "problem_paths = get_problems_path('blocksworld', kind='predictive_power')\n", "\n", "# get first problem file path\n", "problem_path = problem_paths[0]\n", "\n", "# get test set of state for a single problem\n", "test_states = test_states[problem_path.split('/')[-1]]\n", "pprint(test_states)" ] }, { "cell_type": "markdown", "id": "4d9d972d7e58019e", "metadata": {}, "source": [ "Create a simulator defined by the learned domain model and an environment simulator defined by a reference domain model" ] }, { "cell_type": "code", "execution_count": null, "id": "86e3b1cbe0502833", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T10:24:51.575594Z", "start_time": "2026-01-19T10:24:51.340424Z" } }, "outputs": [], "source": [ "from amlgym.modeling.UPEnv import UPEnv\n", "\n", "simulator_learned = UPEnv(domain_learned_path, problem_path)\n", "simulator_ref = UPEnv(domain_ref_path, problem_path)" ] }, { "cell_type": "markdown", "id": "f467a155ecd10cab", "metadata": {}, "source": [ "Evaluate the predicted applicability and predicted effects metrics with a learned domain simulator and environment simulator." ] }, { "cell_type": "code", "execution_count": null, "id": "cbf0b2790848de21", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T10:25:04.164109Z", "start_time": "2026-01-19T10:25:04.131159Z" } }, "outputs": [], "source": [ "from amlgym.metrics import predictive_power\n", "\n", "predictive_metrics = predictive_power(simulator_learned,\n", " simulator_ref,\n", " test_states)\n", "pprint(predictive_metrics)" ] }, { "cell_type": "markdown", "id": "d5b5e855a93ea3f4", "metadata": {}, "source": [ "## Comparing passive learning performances with full observability" ] }, { "cell_type": "markdown", "id": "4634e006b1f79796", "metadata": {}, "source": [ "**Question A: Who achieves higher syntactic precision between NOLAM and OffLAM in domain tpp?**\n", "\n", "Instantiate the learning algorithms:" ] }, { "cell_type": "code", "execution_count": null, "id": "8d1c9a35da3e900e", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T13:25:12.475726Z", "start_time": "2026-01-19T13:25:12.469055Z" } }, "outputs": [], "source": [ "offlam = get_algorithm('offlam')\n", "nolam = get_algorithm('nolam', noise=0.)" ] }, { "cell_type": "markdown", "id": "806fe1518301a026", "metadata": {}, "source": [ "Get an input (empty IPC) domain for tpp and the associated set of learning trajectories:" ] }, { "cell_type": "code", "execution_count": null, "id": "c3789d8988dffcd3", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T13:52:04.825732Z", "start_time": "2026-01-19T13:52:04.772103Z" } }, "outputs": [], "source": [ "domain_path = get_domain_path('tpp')\n", "domain_empty_path = empty_domain(domain_path)\n", "traj_paths = get_trajectories_path('tpp')" ] }, { "cell_type": "markdown", "id": "67cff31da01c7339", "metadata": {}, "source": [ "Learn a domain model specified in PDDL:" ] }, { "cell_type": "code", "execution_count": null, "id": "27f8b237da00f033", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T13:52:08.360669Z", "start_time": "2026-01-19T13:52:07.173974Z" } }, "outputs": [], "source": [ "# Learn a domain model using OffLAM\n", "domain_offlam = offlam.learn(domain_empty_path, traj_paths)\n", "\n", "# Learn a domain model using NOLAM\n", "domain_nolam = nolam.learn(domain_empty_path, traj_paths)" ] }, { "cell_type": "markdown", "id": "acf4b2586fdeb029", "metadata": {}, "source": [ "Store the learned models for evaluation" ] }, { "cell_type": "code", "execution_count": null, "id": "a2d745db5573c9ed", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T13:52:10.853608Z", "start_time": "2026-01-19T13:52:10.850453Z" } }, "outputs": [], "source": [ "domain_offlam_path = 'offlam.pddl'\n", "with open(domain_offlam_path, 'w') as f:\n", " f.write(domain_offlam)\n", " \n", "domain_nolam_path = 'nolam.pddl'\n", "with open(domain_nolam_path, 'w') as f:\n", " f.write(domain_nolam)" ] }, { "cell_type": "code", "execution_count": null, "id": "1f470295bce9df89", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T15:32:38.331892Z", "start_time": "2026-01-19T15:32:38.329975Z" } }, "outputs": [], "source": [ "# ..." ] }, { "cell_type": "markdown", "id": "4bbb9c9135dd36c5", "metadata": {}, "source": [ "**Question B: Who achieves the highest solving ratio among SAM and OffLAM in domain goldminer?**\n" ] }, { "cell_type": "code", "execution_count": null, "id": "6795e73e13bea543", "metadata": { "ExecuteTime": { "end_time": "2026-01-19T15:32:20.129393Z", "start_time": "2026-01-19T15:32:20.126921Z" } }, "outputs": [], "source": [ "# ..." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.6" } }, "nbformat": 4, "nbformat_minor": 5 }