SchedulingProblem

class unified_planning.model.scheduling.SchedulingProblem(name: str | None = None, environment: Environment | None = None, *, initial_defaults: Dict[Type, int | float | Fraction | str | FNode | Object | bool] = {})[source]

Bases: AbstractProblem, UserTypesSetMixin, TimeModelMixin, FluentsSetMixin, ObjectsSetMixin, InitialStateMixin, MetricsMixin

A scheduling problem shares most of its construct with a planning problem with the following differences:

  • scheduling problems replaces actions with activities. While in planning, a solution plan may contain zero, one or multiple instances of the same action, in scheduling the solution must contain exactly one instance of each activity.

  • it defines a set of variables and timepoints over which constraints can be stated,

  • it provides some shortcuts to deal with typical scheduling constructs (activities, resources, …)

  • by default, a SchedulingProblem assumes a discrete time model with a minimal temporal separation (aka epsilon) of 1.

property kind: ProblemKind

Returns the ProblemKind of this Problem.

clone()[source]

Returns an equivalent problem.

add_variable(name: str, tpe: Type) Parameter[source]

Adds a new decision variable to the problem. Such variables essentially act as existentially quantified variables whose scope is the entire problem, which allows referring to them everywhere and access their values in the solution.

get_variable(name: str) Parameter[source]

Returns the existing decision variable with the given name.

add_activity(name: str, duration: int = 0) Activity[source]

Creates a new activity with the given name in the problem.

Parameters:
  • name – Name that uniquely identifies the activity.

  • duration – (optional) Fixed duration of the activity. If not set, the duration to 0 (instantaneous activity). The duration can alter be overriden on the Activity object.

property activities: List[Activity]

Return a list of all potential activities in the problem.

get_activity(name: str) Activity[source]

Returns the activity with the given name.

add_resource(name: str, capacity: int) Fluent[source]

Declares a new resource: a bounded integer fluent in [0, CAPACITY] where capacity is the default initial value of the fluent and denote the capacity of the resource.

Parameters:
  • name – Name of the fluent that will represent the resource.

  • capacity – Upper bound on the fluent value. By default, the fluent initial value is set to capacity.

add_constraint(constraint: FNode | Fluent | Parameter | bool)[source]

Enforce a boolean expression to be true in any solution

add_condition(span: TimeInterval, condition: FNode)[source]
add_effect(timing: Timing | Timepoint | int | float | Fraction, fluent: FNode | Fluent, value: Timing | Timepoint | int | float | Fraction | FNode | Fluent | Parameter | Variable | bool | str | Object, condition: FNode | Fluent | Parameter | Variable | bool = True)[source]
add_increase_effect(timing: int | Timing, fluent: FNode | Fluent, value: Timing | Timepoint | int | float | Fraction | FNode | Fluent | Parameter | Variable | bool | str | Object, condition: FNode | Fluent | Parameter | Variable | bool = True)[source]
add_decrease_effect(timing: Timing | Timepoint | int | float | Fraction, fluent: FNode | Fluent, value: Timing | Timepoint | int | float | Fraction | FNode | Fluent | Parameter | Variable | bool | str | Object, condition: FNode | Fluent | Parameter | Variable | bool = True)[source]
property base_variables: List[Parameter]

Return all decisions variables that were defined in the base problem (i.e. not in the activities)

property base_constraints: List[FNode]

Returns all constraints defined in the base problem (ignoring any constraint defined in an activity).

property base_conditions: List[Tuple[TimeInterval, FNode]]

Returns all timed conditions defined in the base problem (i.e. excluding those defined in activities).

property base_effects: List[Tuple[Timing, Effect]]

Returns all timed effects defined in the base problem (i.e. excluding those defined in activities).

all_variables() List[Tuple[Parameter | Timepoint, Activity | None]][source]

Returns all decision variables (timepoints and parameters) defined in this problem and its activities. For each variable, the activity in which it was defined is also given.

all_constraints() List[Tuple[FNode, Activity | None]][source]

Returns all constraints enforced in this problem or in any of its activities. For each constraint, the activity in which it was defined is also given.

all_conditions() List[Tuple[TimeInterval, FNode, Activity | None]][source]

Returns all timed conditions enforced in this problem or in any of its activities. For each condition, the activity in which it was defined is also given.

all_effects() List[Tuple[Timing, Effect, Activity | None]][source]

Returns all timed effects enforced in this problem or in any of its activities. For each effect, the activity in which it was defined is also given.

normalize_plan(plan: Plan) Plan[source]

Normalizes the given Plan, that is potentially the result of another Problem, updating the Object references in the Plan with the ones of this Problem which are syntactically equal.

Parameters:

plan – The Plan that must be normalized.

Returns:

A Plan syntactically valid for this Problem.

has_name(name: str) bool[source]

Returns True the given name is already used inside this Problem, False otherwise.

Parameters:

name – The target name to search in the Problem.

Returns:

True if the name is already used in the Problem, False otherwise.

add_fluent(fluent_or_name: Fluent | str, typename: Type | None = None, *, default_initial_value: int | float | Fraction | str | FNode | Object | bool | None = None, **kwargs: Type) Fluent

Adds the given fluent to the problem.

If the first parameter is not a Fluent, the parameters will be passed to the Fluent constructor to create it.

Parameters:
  • fluent_or_nameFluent instance or name of the fluent to be constructed.

  • typename – If only the name of the fluent is given, this is the fluent’s type (passed to the Fluent constructor).

  • default_initial_value – If provided, defines the default value taken in initial state by a state variable of this fluent that has no explicit value.

  • kwargs – If only the name of the fluent is given, these are the fluent’s parameters (passed to the Fluent constructor).

Returns:

The fluent passed or constructed.

Example

>>> from unified_planning.shortcuts import *
>>> problem = Problem()
>>> location = UserType("Location")
>>> at_loc = Fluent("at_loc", BoolType(), l=location)  # creates a new fluent
>>> problem.add_fluent(at_loc)  # adds it to the problem
bool at_loc[l=Location]
>>> problem.add_fluent("connected", BoolType(), l1=location, l2=location)  # creates a new fluent and add it to the problem.
bool connected[l1=Location, l2=Location]
>>>
add_fluents(fluents: Iterable[Fluent])

Adds the given fluents to the problem.

Parameters:

fluents – The fluents that must be added to the problem.

add_object(obj_or_name: Object | str, typename: Type | None = None) Object

Add the given object to the problem, constructing it from the parameters if needed.

Parameters:
  • obj_or_name – Either an Object instance or a string containing the name of the object.

  • typename – If the first argument contains only the name of the object, this parameter should contain its type, to allow creating the object.

Returns:

The Object that was passed or constructed.

Examples

>>> from unified_planning.shortcuts import *
>>> problem = Problem()
>>> cup = UserType("Cup")
>>> o1 = Object("o1", cup)  # creates a new object o1
>>> problem.add_object(o1)  # adds it to the problem
o1
>>> o2 = problem.add_object("o2", cup)  # alternative syntax to create a new object and add it to the problem.
add_objects(objects: Iterable[Object])

Adds the given objects to the problem.

Parameters:

objects – The objects that must be added to the problem.

add_quality_metric(metric: PlanQualityMetric)

Adds the given quality metric to the Problem; a quality metric defines extra requirements that a Plan must satisfy in order to be valid.

Parameters:

metric – The quality metric that a Plan of this Problem must satisfy in order to be valid.

property all_objects: List[Object]

Returns the list containing all the objects in the problem.

clear_fluents()

Removes all the Fluent from the current Problem, together with their default.

clear_quality_metrics()

Removes all the quality metrics in the Problem.

property discrete_time: bool

Returns True if the problem time is discrete, False if it is continuous.

property environment: Environment

Returns the Problem Environment.

property epsilon: Fraction | None

it defines the minimum amount of time that can elapse between 2 temporal events. A temporal event can be, for example, the start of an action, the end of an action, an intermediate step of an action, a timed effect of the problem.

When None, it means that this minimum step is chosen by the Engine the Problem is given to.

Type:

This parameter has meaning only in temporal problems

property explicit_initial_values: Dict[FNode, FNode]

Returns the problem’s defined initial values; those are only the initial values set with the set_initial_value() method.

IMPORTANT NOTE: For all the initial values of the problem use initial_values.

fluent(name: str) Fluent

Returns the fluent with the given name.

Parameters:

name – The name of the target fluent:

Returns:

The fluent with the given name.

property fluents: List[Fluent]

Returns the fluents currently in the problem.

property fluents_defaults: Dict[Fluent, FNode]

Returns the problem’s fluents defaults.

get_static_fluents() Set[Fluent]

Returns the set of the static fluents.

Static fluents are those who can’t change their values because they never appear in the fluent field of an Effect, therefore there are no Actions in the Problem that can change their value.

get_unused_fluents() Set[Fluent]

Returns the set of fluents that are never used in the problem.

has_fluent(name: str) bool

Returns True if the fluent with the given name is in the problem, False otherwise.

Parameters:

name – The name of the target fluent.

Returns:

True if the fluent with the given name is in the problem, False otherwise.

has_object(name: str) bool

Returns True if the object with the given name is in the problem, False otherwise.

Parameters:

name – The name of the target object in the problem.

Returns:

True if an object with the given name is in the problem, False otherwise.

has_type(name: str) bool

Returns True if the type with the given name is defined in the problem, False, otherwise.

Parameters:

name – The target name for the type.

Returns:

True if a type with the given name is in the problem, False otherwise.

property initial_defaults: Dict[Type, FNode]

Returns the problem’s fluents defaults for each type.

initial_value(fluent: FNode | Fluent) FNode

Retrieves the initial value assigned to the given fluent.

Parameters:

fluent – The target fluent of which the value in the initial state must be retrieved.

Returns:

The value expression assigned to the given fluent in the initial state.

property initial_values: Dict[FNode, FNode]

Gets the initial value of all the grounded fluents present in the Problem.

IMPORTANT NOTE: this property does a lot of computation, so it should be called as seldom as possible.

property name: str | None

Returns the Problem name.

object(name: str) Object

Returns the object with the given name.

Parameters:

name – The name of the target object in the problem.

objects(typename: Type) Iterator[Object]

Returns the objects compatible with the given Type: this includes the given type and its heirs.

Parameters:

typename – The target type of the objects that are retrieved.

Returns:

A generator of all the objects in the problem that are compatible with the given type.

property quality_metrics: List[PlanQualityMetric]

Returns all the quality metrics in the Problem.

property self_overlapping: bool

The self_overlapping flag determines if 2 (or more) different instances of the same action grounded with the same parameters can be running at the same time.

set_initial_value(fluent: FNode | Fluent, value: int | float | Fraction | str | FNode | Fluent | Object | bool)

Sets the initial value for the given Fluent. The given Fluent must be grounded, therefore if it’s arity is > 0, the fluent parameter must be an FNode and the method is_fluent_exp() must return True.

Parameters:
  • fluent – The grounded Fluent of which the initial value must be set.

  • value – The value assigned in the initial state to the given fluent.

user_type(name: str) Type

Returns the user type in the problem with the given name.

Parameters:

name – The target name for the type.

Returns:

The type in the problem with the given name.

property user_types: List[Type]

Returns the list of all the user types in the problem.

property user_types_hierarchy: Dict[Type | None, List[Type]]

Returns a Dict where every key represents an Optional Type and the value associated to the key is the List of the direct sons of the Optional Type.

All the user types corresponding to the ‘None’ key are fatherless.