aiplan4eu / unified-planning

The AIPlan4EU Unified Planning Library
Apache License 2.0
182 stars 39 forks source link

Adding Intervals to Temporal Planning #58

Closed uwe-koeckemann closed 1 year ago

uwe-koeckemann commented 2 years ago

User Story

As a Timeline-based Planner Provider I want to access implicit or assign explicit intervals to preconditions, effects, actions, states, and goals to impose temporal (and resource) constraints between these intervals.

Acceptance Criteria

Additional Material

import upf

Location = upf.UserType('Location')
robot_at = upf.Fluent('robot_at', BoolType(), [Location])
distance = upf.Fluent('distance', RealType(), [Location, Location])

move = upf.DurativeAction('move', l_from=Location, l_to=Location)
l_from = move.parameter('l_from')
l_to = move.parameter('l_to')

i_move_1 = Interval('C1')
# or: i_move_1 = 'C1_
# similar for other intervals used below ...

# Intervals may be attached as optional arguments:
move.set_duration_constraint(IntervalDuration(5, 16))
move.add_start_condition(Not(Equals(l_from, l_to)), delay=3) 
move.add_condition(StartTiming(), Not(Equals(l_from, l_to)), interval=i_move_1)
move.add_condition(EndTiming(3), robot_at(l_from), interval=i_move_2)
move.add_condition(EndTiming(), Not(robot_at(l_to)), interval=i_move_3)
move.add_effect(StartTiming(), robot_at(l_from), False, , interval=i_move_e_1)
move.add_effect(EndTiming(),robot_at(l_to), True, interval=i_move_e_2)
move.add_durative_condition(LeftOpenInterval(StartTiming(), EndTiming()), Not(robot_at(l_to))) 

i_move = Interval()
move.set_interval(i1)

# add a temporal constraint:
move.add_constraint(Duration(i_move, 10, 20)) # flexible duration
move.add_constraint(Meets(i_move_2, i_move_e_2)) # relate condition and effect
move.add_constraint(Overlaps(i_move_2, i_move)) # relate precondition and action

# attach a resource usage to an interval
r1 = ReusableResource(capacity=1)
move.add_constraint(Use(r1, 1, interval=i_move)

# access condition interval based on add_condition order?
i_move_1_alt = move.get_condition_interval(0) 
assertEquals(i_move_1_alt, i_move_1)

l1 = upf.Object('l1', Location)
l2 = upf.Object('l2', Location)
problem = upf.Problem('robot')
problem.add_fluent(robot_at)
problem.add_durative_action(move)
problem.add_object(l1)
problem.add_object(l2)
problem.set_initial_value(robot_at(l1), True, interval=Interval())
problem.set_initial_value(robot_at(l2), False)
problem.add_timed_effect(100, AssignEffect(robot_at(l2), False))
problem.add_goal(robot_at(l2), interval=Interval()) # At the end of the plan robot is in l2
problem.add_timed_goal(500, robot_at(l1)) # At time 500 robot is in l1
problem.add_maintain_goal(LeftOpenInterval(50, 100), robot_at(l1)) # Between (50 and 100] robot stays in l2

Attention Points

alexander-sung commented 1 year ago

I'd like to add to the relevance of this issue since I'm currently trying to model a problem which has certain fluents set to specific values in some intervals in the future. My understanding is that problem.set_initial_value(robot_at(l1), True, interval=Interval()), as an example, is addressing this.

Additionally, is mentioning actions in the user story also covering actions already being executed at planning time? Referring to the example from https://colab.research.google.com/github/aiplan4eu/unified-planning/blob/master/notebooks/Unified_Planning_Temporal.ipynb, let's say I'm executing the first plan received for 3 seconds but then notice one of the planned matches is broken and I need to replan to use another. At this point in time I would like to specify that one match is already in use, thus giving light. On the other hand, a fuse is currently being mended, so that hand is not free. Instead of reproducing all the actions' effects, it would be convenient to specify actions already being executed. Is this covered here? Otherwise I would create a separate user story, no problem. Let me know in case that's preferred. Thanks.

mikand commented 1 year ago

@uwe-koeckemann Closing this for now: we do have some interval support in temporal and hierarchical planning, but no engines generally support very expressive interval reasoning (at least for now...)