# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# + [markdown] id="6nOTljC_mTMn"
# # Simulated Effects Demo
#
# This python notebook shows the simulated effects usage in the unified planning library.

# + [markdown] id="t8dCcpf7mivV"
# ## Setup the library and the planners

# + [markdown] id="CwlvEzKrm1jT"
# First, we install unified_planning library and its dependencies from PyPi. Here, we use the `--pre` flag to use the latest development build.

# + id="oDJHuFnpc6Ce"
# begin of installation

# + id="BoqALxJWdfl8"
pip install --pre unified-planning[tamer]

# + [markdown] id="iNHFHxQKnKIp"
# We are now ready to use the Unified-Planning library!

# + id="hsy6P3TOdCSn"
# end of installation

# + [markdown] id="9dP5scv7nNJu"
# ## Demo
#

# + [markdown] id="DXhHD7EAmxVx"
# ### Basic imports
# The basic imports we need for this demo are abstracted in the `shortcuts` package.

# + id="fiRk2F1llJO-"
from unified_planning.shortcuts import *

# + [markdown] id="fXA1NuXgkntV"
# ### Problem definition

# + [markdown] id="JXDIDNwCm13b"
# We start the problem modeling defining the `UserType` and the `Fluent`.

# + id="nHXzkD2LmWkB"
Location = UserType('Location')
Robot = UserType('Robot')

at = Fluent('at', Location, robot=Robot)
battery_charge = Fluent('battery_charge', IntType(0, 100), robot=Robot)

# + [markdown] id="OVUn5VPTmXKY"
# We define an action `move` with a simulated effect that models the battery consumption.
#
# A `SimulatedEffect` instance can affect a list of fluent expressions, in this case only `battery_charge(robot)`.
# The function `fun` performs the computation of the simulated effect decreasing the battery value by 10. This function receives as parameters the problem, the state in which the effect is applied, and the actual parameters of the action instance whose effect is being calculated.
#

# + id="cwXh99K2laqv"
move = InstantaneousAction('move', robot=Robot, l_from=Location, l_to=Location)
robot = move.parameter('robot')
l_from = move.parameter('l_from')
l_to = move.parameter('l_to')
move.add_precondition(Equals(at(robot), l_from))
move.add_precondition(GE(battery_charge(robot), 10))
move.add_precondition(Not(Equals(l_from, l_to)))
move.add_effect(at(robot), l_to)
def fun(problem, state, actual_params):
    value = state.get_value(battery_charge(actual_params.get(robot))).constant_value()
    return [Int(value - 10)]
move.set_simulated_effect(SimulatedEffect([battery_charge(robot)], fun))

# + [markdown] id="C92YH1nrmRb7"
# Finally, we define the `Object` instances and, after creating the `Problem`, we set the initial values and the goal.

# + id="MczotRommR_k"
l1 = Object('l1', Location)
l2 = Object('l2', Location)
r1 = Object('r1', Robot)

problem = Problem('robot_with_simulated_effects')
problem.add_fluent(at)
problem.add_fluent(battery_charge)
problem.add_action(move)
problem.add_object(l1)
problem.add_object(l2)
problem.add_object(r1)

problem.set_initial_value(at(r1), l1)
problem.set_initial_value(battery_charge(r1), 100)

problem.add_goal(Equals(at(r1), l2))

# + [markdown] id="pXvh83ljlabv"
# ### Solving the problem

# + [markdown] id="McV4znupqpkw"
# We solve the problem automatically selecting a suitable planner.

# + id="bXHWJh2vl5RJ"
with OneshotPlanner(problem_kind=problem.kind) as planner:
    result = planner.solve(problem)
    print("%s returned: %s" % (planner.name, result.plan))

StarcoderdataJupyterScriptsDedupFiltered