From c9e405bead98fafc9e42df97092c115d0c90f2f5 Mon Sep 17 00:00:00 2001 From: Arthur Bit-Monnot Date: Fri, 15 Dec 2023 19:53:20 +0100 Subject: [PATCH 1/4] doc: polish the Problem Representation section Signed-off-by: Arthur Bit-Monnot --- docs/problem_representation.rst | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/docs/problem_representation.rst b/docs/problem_representation.rst index bf1d393aa..d3fd0e354 100644 --- a/docs/problem_representation.rst +++ b/docs/problem_representation.rst @@ -247,15 +247,25 @@ In all the examples below all the shortcuts must be imported, with the command: Classical and Numeric Planning ------------------------------ -The following example shows a simple robotic planning problem modeling a robot moving between locations while consuming battery. The example shows the basic functionalities and objects needed to declare the problem specification. A more detailed presentation of the different objects is available on the `Google Colab `_ Python notebook where we document and explain all the different classes and their semantics. + +Classical and Numeric planning are the most common problems and the building blocks of most other planning problems. +At their root, they allow the definition of instantaneous that provide: + +- preconditions that allow to check whether the action is applicable in a given state, and +- effects that allow the computation of the resulting state after the action is executed. + +The classical and numeric planning only differ in that classical planning does not allow to referring to numeric variables in the state. +The following example shows a simple robotic planning problem modeling a robot moving between locations while consuming battery. +The example shows the basic functionalities and objects needed to declare the problem specification. +`[Classical detailed presentation 🔗] `__ +`[Numeric detailed presentation 🔗] `__ .. literalinclude:: ./code_snippets/robot_battery.py :lines: 3-38 - + :caption: Syntax Overview In the current version, the Unified-Planning library allows the specification of classical, numerical and temporal planning problems. In order to support the latitude expressiveness levels we have operators for arithmetic such as plus minus times and division and specific temporal operators to attach conditions and effects to specific timings within the duration of an action. The library :ref:`documentation ` provides examples and describes the use of these functionalities. - Temporal Planning ----------------- @@ -266,9 +276,11 @@ This means that it is possible to model actions having: * conditions or effects expressed at specific instant of the action, in particular at times start+delay or end+delay, where start refers to the starting time of the action, end to the ending time and delay is a real constant (positive or negative). * durative conditions to be maintained within sub-intervals, delimited by the same time-point used for instantaneous conditions. +`[Detailed presentation 🔗] `__ + .. literalinclude:: ./code_snippets/temporal_and_scheduling.py :lines: 3-44 - + :caption: Syntax Overview Hierarchical Planning --------------------- @@ -290,7 +302,7 @@ The problem comes in several variants, depending on various features. Specifical .. literalinclude:: ./code_snippets/multi_agent_and_contingent.py :lines: 3-41 - + :caption: Syntax Overview Contingent Planning ------------------- @@ -298,7 +310,7 @@ A contingent planning problem represents an action-based problem in which the ex .. literalinclude:: ./code_snippets/multi_agent_and_contingent.py :lines: 44-95 - + :caption: Syntax Overview Scheduling ---------- @@ -334,4 +346,5 @@ object between a series of waypoints. `[Detailed presentation 🔗] Date: Fri, 15 Dec 2023 23:55:58 +0100 Subject: [PATCH 2/4] doc(optimality): Work on plan quality page to include anytime mode --- docs/optimality.rst | 44 ++++++++++++++++++++++++++++++++------------ justfile | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 12 deletions(-) create mode 100644 justfile diff --git a/docs/optimality.rst b/docs/optimality.rst index 8158cb90c..acfdd8d0e 100644 --- a/docs/optimality.rst +++ b/docs/optimality.rst @@ -1,8 +1,8 @@ .. _engines: -========== -Optimality -========== +====================== +Metrics & Plan Quality +====================== .. contents:: :local: @@ -28,19 +28,39 @@ The UP library defines a set of "Quality Metrics" to express the objective funct Creating quality metrics amounts to instantiate the corresponding object and adding it to one or more `Problem` instances. See the `Optimal Planning Notebook `_ for an example. -Optimal and Satisficing Planning -================================ +Optimal, Anytime and Satisficing Planning +========================================= -Some planning engines can guarantee to find the optimal solution for some kinds of quality metrics, others can only apply a best-effort approach to find good-quality solutions without optimality guarantees. The UP allows the user to explicitly define the desired optimality guarantees as parameters of the operative modes. +When dealing with quality metrics, it is useful to keep the following in mind: -If a planning engine is able to generate a solution result it could be either marked as `SOLVED_OPTIMALLY` or `SOLVED_SATISFICING` to indicate whether the produced solution is guaranteed to be optimal or not. +- A **satisficing** planner will return the first plan found, regardless of its quality. +- An **optimal** planner will only return a provably optimal plan. +- An **anytime** planner will return a series of plan of increasing quality until it runs out of time or is no longer able to improve its last solution. +.. code-block:: -Notes ------ + # By default, Oneshot planner will return the first available solver (typically a satisficing one) + with OneshotPlanner(problem_kind=problem.kind) as planner: + res = planner.solve(utr_problem) + + # An optimal solver can be explicitly required with the optimality_guarantee parameter + with OneshotPlanner(problem_kind=problem.kind, + optimality_guarantee=PlanGenerationResultStatus.SOLVED_OPTIMALLY) as optimal_planner: + res = optimal_planner.solve(utr_problem) -If a planning problem without optimality metrics is required to be solved optimally, an exception is thrown. + # An anytime planner can be requested with the AnytimePlanning operation mode + with AnytimePlanner(problem_kind=problem.kind) as planner: + for res in planner.get_solutions(problem): + print(res) -If a planning problem without optimality metrics is solved by a planning engine capable of guaranteeing some optimality, it is anyway marked as `SOLVED_SATISFICING`. +Proving the optimality of plan can be very time-consuming and orders of magnitude longer than finding it. +Indeed, it requires the planner to prove that all potential alternative plans are of lower quality. +As a rule of thumb, if you are interested in finding high quality solutions but do not care about optimality you should use an anytime planner. +Its runtime can be capped with the ``timeout`` parameter of ``get_solutions()`` or may just break out of the loop when your happy with the returned solution. + +Notes +----- -The UP currently supports only 1 metric in each problem, therefore multi-objective optimization is not possible. +- If a planning problem without optimality metrics is required to be solved optimally, an exception is thrown. +- If a planning problem without optimality metrics is solved by a planning engine capable of guaranteeing some optimality, it is anyway marked as `SOLVED_SATISFICING`. +- The UP currently supports only 1 metric in each problem, therefore multi-objective optimization is not possible. diff --git a/justfile b/justfile new file mode 100644 index 000000000..cbf55bfcb --- /dev/null +++ b/justfile @@ -0,0 +1,35 @@ + + +# Format the code base +format: + python3 -m black --exclude=unified_planning/grpc/generated/ . + +# Check that the code base is correctly formated +check-format: + python3 -m black --check --exclude=unified_planning/grpc/generated/ . + +# Run mypy linter on the code base +check-mypy: + python3 -m mypy unified_planning + +# Generate protobuf bindings +gen-protobuf: + pip show grpcio-tools | grep "Version: 1.54.2" # Check installed version for reproducibility + bash scripts/generate_protobuf_bindings.sh + +# Test one (or more) engine with report +test-engine +engine_name: + python3 up_test_cases/report.py {{engine_name}} + +# Generate the documentation +build-doc target="html": + pip install -r docs/requirements.txt + sphinx-build -M {{target}} docs/ docs/_build -W --keep-going + +# Open local documentation in the browser +open-doc browser="firefox": + {{browser}} docs/_build/html/index.html + +# Install unified-planning from sources +install: + pip install . \ No newline at end of file From 737d1a7b6fade1559ea5b557a882d2fcf944d7f1 Mon Sep 17 00:00:00 2001 From: Arthur Bit-Monnot Date: Fri, 15 Dec 2023 23:56:53 +0100 Subject: [PATCH 3/4] doc(contributor): Expand the contributor guide to be more exhaustive and reference the just file --- docs/contributor_guide.rst | 42 +++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/docs/contributor_guide.rst b/docs/contributor_guide.rst index 304df7f9c..5979e3d20 100644 --- a/docs/contributor_guide.rst +++ b/docs/contributor_guide.rst @@ -1,7 +1,30 @@ Contributor's Guide =================== +This page is dedicated to the technical information that you may find useful when contributing code or documentation to the UP repository. +For information on the contribution process, please have a look to the `corresponding page `_. +Common commands (Justfile) +-------------------------- + +A list of common commands and recipes are available in a `justfile `_. +You can use it to find out common commands (e.g. running tests, reformatting the code) or use it directly with the `just `_ command line tool. + +Whenever you see a command ``just RECIPE_NAME`` in this page, it means the command is available as a just recipe. +You can run it directly with ``just`` or check the ``justfile`` for the actual commands to run. + +Checklist +--------- + +Before sending a pull-request, you should check the following conditions: + + - your code is properly formatted with ``black`` (``just format``) + - your code passes the linter check (``just check-mypy``) + - your code passes all existing unit tests + - you have added tests to ensure that your change is and remains valid + - you have updated the documentation to reflect your changes + +Whenever possible these are automatically check in CI. Documentation ------------- @@ -13,8 +36,7 @@ It consists of a collection of reStructuredText documents and python notebooks t Building the documentation ^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The documentation can be built locally like so:: +The documentation can be built locally like so (``just build-doc``):: cd docs/ # enter the documentation folder pip install -r requirements.txt # install documentation toolchain @@ -30,11 +52,21 @@ The reference API part of the documentation is built automatically by the `docs/ The script contains the list of classes that will appear in the documentation. If you contribute a new *user-facing* class, the list of classes should be updated to make it appear in the API reference. +Ensuring documentation consistency +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +As much as possible, we strive to make example code testable to ensure that it remains valid when updating the library. +This notably include all code in ``docs/code_snippets`` as well as all notebooks in ``docs/notebooks``. +If your notebook has some code that should *not* be run in CI, the corresponding cell should be tagged with the ``remove_from_CI`` flag. +Protobuf bindings +----------------- +The UP provides protobuf bindings that can be used export the problems modeled with the UP in a protobuf format. +The schema for this format are available in the `unified_planning/grpc/unified_planning.proto `_ file. -Issue Tracking --------------- +When updating them you should ensure that: -Issue tracking is done in GitHub issues: https://github.com/aiplan4eu/unified-planning/issues + - the schema remains backward compatible (no removal, no change in the fields indices) + - you have regenerated the python bindings available in the repository (``just gen-protobuf``) From 8bc0b6b2f21d0ae0b941c4e496c0758c28e6410e Mon Sep 17 00:00:00 2001 From: Arthur Bit-Monnot Date: Fri, 15 Dec 2023 23:57:35 +0100 Subject: [PATCH 4/4] doc: expand the getting started page, with a video introducing the project --- docs/getting_started.rst | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 24b2d65e8..e8c2f6b3d 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -9,12 +9,18 @@ In this guide we present the main functionalities offered by the Unified-Plannin .. toctree:: - :maxdepth: 2 + :maxdepth: 1 :glob: - :hidden: - :caption: Getting Started getting_started/whats_planning getting_started/installation getting_started/quickstart notebooks/tutorial/modeling.ipynb + +.. raw:: html + + + + + +