1 Introduction

Within the new planning library Plains, which is developed at the German Space Operations Center (GSOC), timelines are defined over the rational numbers to avoid introducing rounding issues due to a fix grid size or the use of IEEE floating point numbers. To make this possible, we are using the high-performance rational number implementation of the Spire algebra library, see [1]. One task of Plains is to determine the set of possible timeline entries of an activity from which the most suitable timeline entry may be chosen to be added to the timeline. In this way, Plains resembles other planning systems like most of those mentioned in [7]: APSI in [10], ASPEN in [6], EUROPA from [3], flexplan in [12, 13], Mexar2 from [5], MUSE in [16], Pinta/Plato from [8, 18] and SPIKE in [15, 22, ch.14]. As each timeline entry consists of a start-time and an end-time, timeline entries are in fact points in the two-dimensional plane with start-time mapped to the x-axis and \({duration } = {end }\hbox {-}{} time - {start }\hbox {-}{} time\) mapped to the y-axis. Selecting a good data structure to represent such sets of timeline entries  therefore, is very important.

In the first section of this paper, we present the PolygonStack, which is used in Plains to efficiently represent such sets of timeline entries. The PolygonStack supports efficient Boolean operations to allow combining the impacts of multiple constraints, it supports checking whether a timeline entry belongs to it and it supports selecting an element according to a proper criterion. A useful property of the PolygonStack is that it uses a compact representation with a canonical choice, i.e. there is a preferable way to represent a given set of timeline entries. This has advantages for determinism of the calculation as well as the ability to speed up complex constraint computations using the process of memoization.

Contrary to existing concepts for representing two-dimensional polygons, a solution set for planning must be able to efficiently represent point solutions (an activity can be planned at exactly one point in time and duration), line solutions (e.g., an activity can be scheduled in a certain time range, but only with a fixed duration), area solutions (e.g., an activity can be scheduled within a time range and a duration range) or any arbitrarily complex combination thereof.

Following the approach of [20, ch. 5.1] (see also [23]), we associate with every point in the solution space a positive integer value. Set membership can, thus, be easily expressed using a convention like 0 for true and \(\ge 1\) for false. Additionally, having an integer value at each point in the solution space gives us more options to combine solution sets and simplifies implementing Boolean operations. Another benefit of [20 ch. 5.1], compared to most other existing concepts of polygons, such as [4, 11, 14, 24], is that we do not consider sorted sets of edges or vertices but just a non-sorted collection of rays. In contrast to [20, ch. 5.1], however, we need to distinguish between values within the inner part of a polygon and the values at its edges and vertices.

In the second section, we introduce the concept of Sliders and Offsets, which extends the capabilities of common planning modeling languages by allowing to formulate a constraint not only relative to the start-time or the end-time of a timeline entry but also relative to any time in between or even outside the timeline entry. Benefit of this new feature is that we may avoid splitting an activity into sub-activities in case multiple constraints refer to different time ranges relative to the activity. For example, a radar image acquisition may require power during its image observation phase; the on-board data compression mechanism, however, may block the on-board memory for twice the time of the image acquisition duration. With our new approach, both constraints may be defined on the same activity, even if the activity’s duration is variable.

The downside of this new feature is that it creates additional work as for each constraint we need to convert the set of available timeline entries into the set of constraint interval start-times and end-times before we can apply the constraint restriction and thereafter convert back the result. The main part of this section, therefore, presents the generic formulas required to implement this conversion.

To clarify how these formulas may be applied, we present the implementation on PolygonStacks. Using selected examples for the conversion, we highlight what problems occur and how these can be solved. Thereafter, we present a worst case estimation for the complexity of the PolygonStack operations.

2 Polygon stacks

A timeline entry comprises a start-time and a duration, both of which shall take rational values. Therefore, one can identify a timeline entry with a rational point in the upper half plane \({\mathbb {H}}\), where the x-axis corresponds to the start-time and the y-axis to the duration of a timeline entry implying \(y\ge 0\). To represent a set S of rational timeline entries, we use functions \(p:{\mathbb {H}} \cap {\mathbb {Q}}\times {\mathbb {Q}}\longrightarrow {\mathbb {N}}_0\) such that

$$\begin{aligned} E \in S \iff p(E) = 0. \end{aligned}$$

For our purpose, we can further restrict to the future of some base time \(X_0\in {\mathbb {Q}}\) yielding a domain \(D\subset {\mathbb {H}} \cap {\mathbb {Q}}\times {\mathbb {Q}}\) defined by

$$\begin{aligned} (x,y) \in D \Longleftrightarrow&\quad x\in {\mathbb {Q}}\text {, s.t. }x \ge X_0\text { and} \end{aligned}$$
(1)
$$\begin{aligned}&\quad y\in {\mathbb {Q}}\text {, s.t. }y \ge 0. \end{aligned}$$
(2)

We define functions \(p:D\longrightarrow {\mathbb {N}}_0\), called PolygonStack, by finite sums

$$\begin{aligned} p = \sum _{r: {\text {Ray}}}r, \end{aligned}$$

where each ray\(r={\text {Ray}}(x_r, y_r, s_r, d_{\text {At},r}, d_{\text {Above},r})\) with

$$\begin{aligned} x_r\in {\mathbb {Q}} \text { (Time)}&=\text { time of}\, r\text {'s starting point} \\ y_r\in {\mathbb {Q}}_{\ge 0} \text { (Duration)}&=\text { duration of}\, r\text {'s starting point} \\ s_r \in {\mathbb {Q}} \cup \{\infty \}&=\text { slope of} \,r \\ d_{\text {At},r}\in {\mathbb {Z}}&=\text { addend on}\, r\text {'s half line} \\ d_{\text {Above},r}\in {\mathbb {Z}}&=\text { addend above}\, r\text {'s half line} \end{aligned}$$

defines a function \(r: D\longrightarrow {\mathbb {Q}}\) as follows:

  • If \(s_r = \infty\), for any \(E=(x, y)\in D\)

    $$\begin{aligned} r(E)= {\left\{ \begin{array}{ll} d_{\text {At},r} &{} E=(x_r, y_r) \\ d_{\text {Above},r} &{} E=(x_r, y)\text { with }y> y_r\\ 0 &{} \text {otherwise} \end{array}\right. } \end{aligned}$$
  • If \(s_r\in {\mathbb {Q}}\), for any \(E=(x, y)\in D\)

    $$\begin{aligned} r(E)= {\left\{ \begin{array}{ll} d_{\text {At},r} &{} x> x_r\text { and }y_r+s_r(x-x_r)=y \\ d_{\text {Above},r} &{} x > x_r\text { and }y_r+s_r(x-x_r)<y\\ 0 &{} \text {otherwise} \end{array}\right. } \end{aligned}$$

The difference to boost’s version of the PolygonStack (see [20, ch. 5.1]) is that we distinguish in between \(d_{\text {At}}\) and \(d_{\text {Above}}\) and that we support a ray with infinite slope. This way we can specify different values for vertices, edges and inner parts of two-dimensional polygons.

2.1 Examples

Fig. 1
figure 1

Rays. \({\text {ray}}_1(1,1)=2\), \({\text {ray}}_1(1,y)=3 \text { for } y > 1\), \({\text {ray}}_2(x, y)=4 \text { for } y = 1 + \frac{1}{2}(x - 2) , x > 2\), \({\text {ray}}_2(x, y)=5 \text { for } y> 1 + \frac{1}{2}(x - 2) , x > 2\)

Fig. 2
figure 2

Polygon stack forming a parallelogram: \((2,1) \rightarrow 2\), \((2,2) \rightarrow 3-1=2\), left vertical edge \(\rightarrow 3\), inner part and right vertical edge \(\rightarrow 5\), lower edge and its right endpoint \(\rightarrow 4\), upper edge and its right endpoint \(\rightarrow 5 - 1 = 4\), dashed lines, dotted and white region \(\rightarrow 0\)

Figure 1 shows a PolygonStack consisting of one ray with finite slope and one ray with infinite slope. Figure 2 shows a PolygonStack with the shape of a parallelogram.

2.2 Operations

To evaluate this representation of a PolygonStack as a set of rays, we need to describe our use cases.

2.2.1 Planning horizon

To simplify some calculations, we will need PolygonStacks which have value 1 outside a bounded region. For this, we introduce the ambient value which is a constant \(C\in {\mathbb {N}}_0\) added to all points, denoted by \({\text {PolygonStack}}(C,\{\text {Rays}\})\), e.g.,

$$\begin{aligned} P = {\text {PolygonStack}}(1, \{{\text {Ray}}(0, 0, 0, -\,1, -\,1)\}) \end{aligned}$$

denotes the (non-bounded) polygon stack with corresponding function \(D\longrightarrow {\mathbb {N}}_0\)

$$\begin{aligned} {\left\{ \begin{array}{ll} 0 &{} \text {if }x>0 \text { and }y\ge 0 \\ 1 &{} \text {otherwise.} \end{array}\right. } \end{aligned}$$

2.2.2 Addition

As mentioned above, we need to consider multiple constraints, each of which restricts the set of consistent timeline entries. Such a restriction shall be represented by a PolygonStack with value greater than zero for all timeline entries which have a conflict with respect to this constraint. The PolygonStacks of all constraints, therefore, need to be added to specify all conflict free timeline entries as those with value 0. Adding two PolygonStacks requires summing up the ambient values, collecting the rays of the two PolygonStacks and merging rays of same x, y and \({slope }\) to one ray with \(d_{\text {At}}\) and \(d_{\text {Above}}\) set to the sum of the respective values.

2.2.3 Evaluation

To evaluate a PolygonStack P on a timeline entry \(E = (x,y)\), we need to consider all rays \(r = {\text {Ray}}(x_r, y_r, s_r, d_{\text {At},r}, d_{\text {Above},r})\) of P with

$$\begin{aligned}&s_r \in {\mathbb {Q}}, x_r<x, y_r + s_r (x - x_r) \le y\\ \text {or }&s_r = \infty , x_r = x, y_r \le y \end{aligned}$$

and add the respective \(d_{\text {At}}\) or \(d_{\text {Above}}\). Geometrically, this corresponds to rays whose line lies at or below the timeline entry E.

2.2.4 Scan for value

When asking which timeline entries an activity may be given, we are not interested in the precise set of violated constraints but only in the region where timeline entries are conflict free. We, therefore, provide a function to simplify a PolygonStack such that it only takes values in \(\{0, 1\}\). More precisely: given a PolygonStack P, we derive a PolygonStack Q with values

$$\begin{aligned} Q(E) = 1 \iff P(E) > 0,\\ Q(E) = 0 \iff P(E) = 0. \end{aligned}$$

For this task, we first need to determine all vertical scan-lines\(x_1< \cdots < x_n\) where either a ray starts or two rays cross. For all scan-lines\(x_i\), we then need to consider all rays with finite slope starting before \(x_i\) and all rays with infinite slope starting at \(x_i\). For all open intervals \((x_i, x_{i+1})\), we need to consider all rays with finite slope starting before \(x_i\). For each ray \(r={\text {Ray}}(x_r, y_r, s_r, \_, \_)\) let \(y(r, x)= x_r + s_r(x - x_r)\) denote the y value of the crossing point of r’s line and the scan-linex. Traversing the rays ascending in y(rx) and \(s_r\), one can derive the regions of values within the considered x-axis interval and build up the resulting PolygonStack Q. Note that multiple rays with equal y(rx) and \(s_r\) can be considered as effectively one ray by summing up their \(d_{\text {At}}\) and \(d_{\text {Above}}\). Rays belonging to the same line in this way occur quite often, because most rays need to be canceled at a later x, e.g., for bounded PolygonStacks. When implementing this operation, one can significantly improve performance by considering the hints provided in [20, ch. 5.1].

2.2.5 Find value

From now on, we consider a PolygonStack P as synonymous with the set of points E with \(P(E) = 0\). Also, we emphasize again that our PolygonStacks are assumed to be finite.

Since a PolygonStack represents a set of timeline entries satisfying some constraints, we would like to select a specific timeline entry from within that set by some configurable algorithm. We choose to define an ordering by specifying a directed line \(L_1\). Two points in the plane are compared by comparing their perpendicular projections on \(L_1\). The points which are mapped to the first point on \(L_1\) w.r.t. its direction are considered best points. Since this step might result in a set of best points, we require a second directed line \(L_2\), which is not parallel to \(L_1\), yielding a unique result for any non-empty, bounded, closed PolygonStack, see Fig. 3.

Fig. 3
figure 3

Sort criterion for elements of PolygonStack; \(L_1\): black marked points are best on P; \(L_2\): (4, 1) is the best among the black marked points

In Fig. 3, \(L_1\) corresponds to earliestend-time (i.e., smallest sum of start-time and duration) and \(L_2\) corresponds to minimum duration. Note that the best point does not need to exist in case the PolygonStack has excluded edges or vertices or is unbounded. In this case, the algorithm must choose a value within the PolygonStack which is close to the best point of the closure of P. For the following lemma, we restrict, thus, to closed PolygonStacks.

Lemma 1

For closed PolygonStack s, the best point is either the starting point of a ray or the crossing point of two rays.

Proof

For a point E which is neither part of a scan-line nor part of a ray’s line, there exists a (2-dimensional) open neighborhood contained in the PolygonStack with the same value, which, when perpendicularly mapped to \(L_1\), is mapped to a (1-dimensional) open neighborhood of the image of E, which means that E is not best w.r.t. \(L_1\). For a point E, which is on a scan-line or on a ray’s line and which is not a starting point of a ray or a crossing point of two rays, there exists an open neighborhood on the respective line with the same value. If this neighborhood is mapped to a neighborhood of the image of E, E is again not best w.r.t. \(L_1\). If the neighborhood of E is not mapped to a neighborhood of E, it must be mapped to the same value as E, which means that all points of the neighborhood of E are equally good w.r.t. \(L_1\). In this case, \(L_2\) applies and this time the neighborhood must be mapped to a neighborhood of E, because \(L_2\) is not parallel to \(L_1\), and again E is not a best point. \(\square\)

We, therefore, can restrict the search for the best point to the finite set of starting points and crossing points.

3 Polygon Stack Conversion

3.1 Modeling example

To understand how this data structure shall be applied, we consider an example for which our planning library shall be suitable: an on-ground fire detecting satellite shall perform observations according to on-ground defined target regions. The corresponding on-board procedure might be defined as follows:

  1. 1.

    10 s before image acquisition, the ACS (Attitude Control System) starts acquiring the required start position.

  2. 2.

    Thereafter, image acquisition is performed. The duration of the image acquisition depends on the target region and, therefore, is variable.

  3. 3.

    Thereafter, image analysis is performed to detect hot spots within the image. The duration of the image analysis is proportional to the duration of the image acquisition, since image analysis is proportional to the amount of data. In this example, we assume that image analysis and image acquisition have same duration.

In our model, we want to define an activity detectFire, which starts at image acquisition start and ends at image analysis end. For this activity, we want to formulate the following constraints:

  1. 1.

    during the interval \(\left[ start - 10 sec , start + \frac{1}{2} duration\right]\) the ACS system is allocated, i.e., no other ACS relevant activities may be performed

  2. 2.

    during the interval [startend] the memory unit is allocated, i.e., no other memory relevant activities may be performed

With our approach of Sliders and Offsets, we can directly formulate both constraints. In traditional planning systems (see [21]), we only have the possibility to define constraints of types

  1. 1.

    at start the condition must hold at the activity’s start-time (possibly plus some predefined constant offset),

  2. 2.

    at end the condition must hold at the activity’s end-time (possibly plus some predefined constant offset),

  3. 3.

    over all the condition must hold during the activity’s time interval (possibly adapted by predefined constant offsets) or

  4. 4.

    \(in\ \iota \ dur\ \delta\) the condition must hold for some subinterval of duration \(\delta\) within a given interval \(\iota\), where the interval bounds of \(\iota\) may refer to timeline entry start or end plus some constant offset.

Even with the concept of relative ordering ([21], section 5.1) we cannot directly refer to a linear combination of start-time and end-time, which means that in traditional planning systems we have to define at least two activities: one representing the ACS activities and one representing the memory allocation, including the image acquisition and the image analysis. These two activities need to be coupled by the information

ACS activities last 10 seconds and end in the middle of a memory allocation start.

Blowing up the model to be able to formulate proper constraints is rather awkward, the main drawback about this solution, however, concerns the algorithm: To begin with, as no constraint may refer to the middle, this information must be considered by the algorithm, violating the concept of separation of algorithm and constraint modeling. Above all, however, heuristic reasoning about the valid timeline entries is much easier if all constraints are defined on one activity, because you can intersect the valid timeline entries of each constraint of the activity. If you need to consider multiple coupled activities, you can not consider one after another, unless you implement a complex repair algorithm or a sophisticated preview mechanism.

With the concept of Sliders and Offsets, we provide a simple way to model such linearly coupled constraints. To intersect constraints with different sliders (domain filtering), we need to introduce the Polygon Stack Conversion, which we describe in the remaining section of this paper.

3.2 Sliders and Offsets

In order to model the above-described example (see 3.1), one may introduce two resources, acsInUseIndicator and memoryInUseIndicator, both of which are given an initial constant value 0 and an upper bound 1. Each activity which uses ACS (including the activity detectFire) is given a constraint which increases the value of acsInUseIndicator by 1 wherever the activity is planned. This way planning two activities in parallel, which both use ACS, would cause a conflict, because the resource acsInUseIndicator would have value 2 during times where two activities overlap. Similarly all activities, which read from or write to memory, are given a constraint to increase the memoryInUseIndicator, which prevents two such activities from being planned in parallel. Note that the modification profiles of the constraints are not absolute time-based profiles but duration-based profiles, which still need to be mapped to the time axis via the activity’s timeline entry (see [8]): only when we know where the activity starts and ends, can we derive the time profile, which is added to the resource profile. As stated in 3.1, the traditional mappings at start, at end and over all are not sufficient to specify the mapping we desire in our example. Instead, we define a start-reference and an end-reference  each of which consists of a \({slider }\in {\mathbb {Q}}\) and an \({offset }\in {\mathbb {Q}}\). Each reference \(({slider }, {offset })\) transforms a timeline entry \(E = ({start }\hbox {-}{} time , {duration })\) to a time T via an affine transformation

$$\begin{aligned} T = {start }\hbox {-}{} time + {slider } \cdot {duration } + {offset } \end{aligned}$$

In our example, we want to formulate that the constraint shall apply starting 10 s before the timeline entry until the middle of the timeline entry. With our definition, we can achieve this by setting:

$$\begin{aligned} {start }\hbox {-}{reference }&= (0, -\,10) \\ {end }\hbox {-}{reference }&= \left( \frac{1}{2}, 0\right) . \end{aligned}$$

Note that the type of the resource and the effects on it have nothing to do with the concept of Sliders and Offsets. In our example, we chose constraints, which allocate a boolean resource, but we could also add another constraint referring, e.g., to the state of charge of a battery, where the effect of planning the activity could be that the resource’s profile is reduced by a constant rate, starting and ending at times, specified by one Sliders and Offsets each.

Also note that the concept of Sliders and Offsets may be applied to time dependencies, too, where one slider is defined for both predecessor and successor and one common offset specifies the minimum separation in between the two times derived from the activities’ timeline entries.

As described in Sect. 3.1, the benefit of introducing Sliders and Offsets is that it simplifies the planning model and the planning algorithm. Unfortunately, this introduces significant complexity within our main use case, finding the set of conflict free timeline entries for a given activity. For this, each constraint must produce a PolygonSet indicating the set of conflicting timeline entries, which now needs to reflect slider and offset. In addition to this, the performance of resource dependency calculations may be improved significantly by cutting off time intervals which are out of scope due to other constraints. This cut-off, however, is not obvious due to the use of sliders.

To solve this challenge, we distinguish in between two different domains, the Timeline Entry Domain, which represents sets of timeline entries and the Constraint Domain, which represents sets of profile intervals, and we provide a conversion in between them.

3.2.1 Timeline Entry Domain

The Timeline Entry Domain consists of all PolygonSets (i.e., PolygonStacks with values in \(\{0, 1\}\)), which represent timeline entries. An entry of the form \((x,y)_{\mathrm{T}} \text { with } y \ge 0\), therefore, represents a timeline entry with \({start }\hbox {-}{} time = x\) and \({duration } = y\).

3.2.2 Constraint Domain

The Constraint Domain consists of all PolygonSets, whose values represent the start-times and durations of constraint intervals, i.e., an element \((a, b)_{\mathrm{C}}\) of a PolygonSet in Constraint Domain represents the interval \([a, a+b)\) to which the constraint’s duration-based profile is mapped to. For our example of an upper resource bound with start-reference\({ref }_{\mathrm{s}} = (f_{\mathrm{s}}, o_{\mathrm{s}})\) and end-reference\({ref }_{\mathrm{e}} = (f_{\mathrm{e}}, o_{\mathrm{e}})\), an element \((a,b)_{\mathrm{C}}\) of a PolygonSet in the Constraint Domain represents the start-time and duration of a timeline entry after it has been transformed using the two references. This means, given a timeline entry \(E_{\mathrm{T}}=(x,y)_{\mathrm{T}}\), the corresponding constraint interval \(E_{\mathrm{C}}=(a,b)_{\mathrm{C}}\) is given by

$$\begin{aligned} a(x, y)&= x + f_{\mathrm{s}} y + o_{\mathrm{s}}, \end{aligned}$$
(3)
$$\begin{aligned} b(x, y)&= (x + f_{\mathrm{e}} y + o_{\mathrm{e}}) - a \nonumber \\&= (f_{\mathrm{e}} - f_{\mathrm{s}}) y + o_{\mathrm{e}} - o_{\mathrm{s}}. \end{aligned}$$
(4)

The reverse relation can be easily obtained from (3) and (4) as

$$\begin{aligned} y(a, b)&= \frac{b - o_{\mathrm{e}} + o_{\mathrm{s}}}{f_{\mathrm{e}} - f_{\mathrm{s}}}, \end{aligned}$$
(5)
$$\begin{aligned} x(a, b)&= a - o_{\mathrm{s}} - f_{\mathrm{s}} y(a, b) \nonumber \\&= a - o_{\mathrm{s}} - f_{\mathrm{s}} \frac{b - o_{\mathrm{e}} + o_{\mathrm{s}}}{f_{\mathrm{e}} - f_{\mathrm{s}}} \end{aligned}$$
(6)

for \(f_{\mathrm{e}}\ne f_{\mathrm{s}}\). Note that in case \(f_{\mathrm{s}}=f_{\mathrm{e}}\), the constraint profile interval’s duration is constant, no matter how long the timeline entry lasts. This case needs to be handled separately; however, it turns out that it can be easily solved using (3).

3.2.3 Domain filtering

Provided we can convert in between these two domains, we may apply the domain filtering of one constraint (i.e., reducing the set of allowed timeline entries) as follows:

  1. 1.

    optional convert the PolygonStack of valid timeline entries of previously considered constraints into a PolygonStack representing the corresponding constraint intervals of the current constraint. This PolygonStack can be used to restrict the resource profile of current constraint’s resource to regions where it may be affected by non-conflicting timeline entries

  2. 2.

    determine the PolygonStack of valid constraint intervals for the current constraint, possibly based upon the restricted resource profile

  3. 3.

    convert the PolygonStack of valid constraint intervals for the current constraint into a PolygonStack representing the valid timeline entries  according to this constraint

  4. 4.

    intersect the PolygonStack of valid timeline entries of this constraint with the PolygonStack of valid timeline entries of previously considered constraints

When provided with this conversion, the implementation of the constraint may omit the Sliders and Offsets and, therefore, is as simple (or complex) as without them.

3.2.4 Example

As an example, let us consider an upper resource bound with a constant profile 0, where the profile start is included and its end is excluded (extending our original example, this constraint may belong to an activity, which requires ACS to be inactive). The constraint’s implementation without slider and offset returns a PolygonStack containing all (ab) such that the resource’s profile remains less than or equal to zero during the time interval \([a, a + b)\). To find the set of timeline entries, which do not violate this constraint, we need to convert this PolygonStack from Constraint Domain to Timeline Entry Domain.

3.3 Converting PolygonStacks in between Timeline Entry Domain and Constraint Domain

Whereas Sect. 3.2.2 describes how to convert one element of a PolygonSet, the main challenge is to convert rays and, thus, PolygonStacks from one domain to the other. This shall be described in this section.

Note that in case \(f_{\mathrm{s}} = f_{\mathrm{e}}\), the duration of the constraint interval is constant for all timeline entries. It turns out that this special case can easily be handled separately, we, therefore, assume in the remaining part of the paper that

$$\begin{aligned} f_{\mathrm{s}} \ne f_{\mathrm{e}}. \end{aligned}$$
(7)

Also note that the transformation is affine linear and, thus, maps lines to lines.

Lemma 2

Let\(s_{\mathrm{T}}\)denote the slope of a line inTimeline Entry Domain, then the corresponding line inConstraint Domainhas slope\(s_{\mathrm{C}}\)with

Proof

Let

$$\begin{aligned} L_{\mathrm{T}}(x, y, s_{\mathrm{T}}) = \{(x + \delta , y + \delta s_{\mathrm{T}}) \in ({\mathbb {Q}} \times {\mathbb {Q}})\mid \delta \in {\mathbb {Q}}\} \end{aligned}$$

define a line in the Timeline Entry Domain passing through (xy) with slope \(s_{\mathrm{T}}\). According to (3) and (4), its image \(L_{\mathrm{C}}\) in the Constraint Domain consists of \((\alpha , \beta )\in {\mathbb {Q}}\times {\mathbb {Q}}\) with

$$\begin{aligned} \alpha&= x + \delta + f_{\mathrm{s}} (y + \delta s_{\mathrm{T}}) + o_{\mathrm{s}} \\&= x + f_{\mathrm{s}} y + o_{\mathrm{s}} + (1 + f_{\mathrm{s}} s_{\mathrm{T}}) \delta \quad \text {and} \\ \beta&= (f_{\mathrm{e}} - f_{\mathrm{s}})(y + \delta s_{\mathrm{T}}) + o_{\mathrm{e}} - o_{\mathrm{s}} \\&=(f_{\mathrm{e}} - f_{\mathrm{s}})y + o_{\mathrm{e}} - o_{\mathrm{s}} + (f_{\mathrm{e}} - f_{\mathrm{s}}) s_{\mathrm{T}} \delta . \end{aligned}$$

In case \(f_{\mathrm{s}} s_{\mathrm{T}} = -1\), we see that \(\alpha\) is constant and according to (7) \(\beta\) takes all values in \({\mathbb {Q}}\), thus \(L_{\mathrm{C}}\) is a vertical line and has infinite slope. For \(f_{\mathrm{s}} s_{\mathrm{T}} \ne -1\), we obtain for points \((\alpha , \beta )\in L_{\mathrm{C}}\)

$$\begin{aligned} \alpha&= a(x,y) + (1 + f_{\mathrm{s}} s_{\mathrm{T}}) \delta \\&= a(x,y) + {\varDelta } \qquad \text {and} \\ \beta&= b(x,y) + (1 + f_{\mathrm{s}} s_{\mathrm{T}}) \delta \frac{(f_{\mathrm{e}} - f_{\mathrm{s}}) s_{\mathrm{T}}}{(1 + f_{\mathrm{s}} s_{\mathrm{T}})} \\&= b(x,y) + {\varDelta } \frac{(f_{\mathrm{e}} - f_{\mathrm{s}}) s_{\mathrm{T}}}{(1 + f_{\mathrm{s}} s_{\mathrm{T}})}, \end{aligned}$$

where \({\varDelta }=(1+f_{\mathrm{s}} s_{\mathrm{T}})\delta\), yielding the slope (8). \(\square\)

Lemma 3

A line with slope\(s_{\mathrm{C}}\)inConstraint Domaincorresponds to a line with slope\(s_{\mathrm{T}}\)inTimeline Entry Domain, where

Proof

Let

$$\begin{aligned} L_{\mathrm{C}}(a, b, s_{\mathrm{C}}) = \{(a + \delta , b + \delta s_{\mathrm{C}}) \in ({\mathbb {Q}} \times {\mathbb {Q}})\mid \delta \in {\mathbb {Q}}\} \end{aligned}$$

denote a line through (ab) with slope \(s_{\mathrm{C}}\) in the Constraint Domain. According to (5) and (6), its image \(L_{\mathrm{T}}\) in the Timeline Entry Domain is given by \((\chi , \psi )\in {\mathbb {Q}}\times {\mathbb {Q}}\) such that

$$\begin{aligned} \chi&= a + \delta - o_{\mathrm{s}} - f_{\mathrm{s}} \frac{b + \delta s_{\mathrm{C}} - o_{\mathrm{e}} + o_{\mathrm{s}}}{f_{\mathrm{e}} - f_{\mathrm{s}}} \\&= a + \delta - o_{\mathrm{s}} - f_{\mathrm{s}} \frac{b - o_{\mathrm{e}} + o_{\mathrm{s}}}{f_{\mathrm{e}} - f_{\mathrm{s}}} - \frac{f_{\mathrm{s}} \delta s_{\mathrm{C}}}{f_{\mathrm{e}} - f_{\mathrm{s}}} \\&= a + \delta - o_{\mathrm{s}} - f_{\mathrm{s}} y(a, b) - \frac{f_{\mathrm{s}} \delta s_{\mathrm{C}}}{f_{\mathrm{e}} - f_{\mathrm{s}}} \\&= x(a, b) + \delta - \frac{f_{\mathrm{s}} \delta s_{\mathrm{C}}}{f_{\mathrm{e}} - f_{\mathrm{s}}} \\&= x(a, b) + \delta \left( 1 - \frac{f_{\mathrm{s}} s_{\mathrm{C}}}{f_{\mathrm{e}} - f_{\mathrm{s}}}\right) \quad \text {and} \\ \psi&= \frac{b + \delta s_{\mathrm{C}} - o_{\mathrm{e}} + o_{\mathrm{s}}}{f_{\mathrm{e}} - f_{\mathrm{s}}} \\&= \frac{b - o_{\mathrm{e}} + o_{\mathrm{s}}}{f_{\mathrm{e}} - f_{\mathrm{s}}} + \frac{\delta s_{\mathrm{C}}}{f_{\mathrm{e}} - f_{\mathrm{s}}} \\&= y(a, b) + \delta \frac{s_{\mathrm{C}}}{f_{\mathrm{e}} - f_{\mathrm{s}}} \end{aligned}$$

If \(f_{\mathrm{e}} = f_{\mathrm{s}}(1 + s_{\mathrm{C}})\) we see that \(\psi\) is constant and \(\chi\) takes all values in \({\mathbb {Q}}\), thus \(L_{\mathrm{T}}\) is a vertical line and has infinite slope. In case \(f_{\mathrm{e}} \ne f_{\mathrm{s}}(1 + s_{\mathrm{C}})\), we obtain a slope

$$\begin{aligned} s_{\mathrm{T}}&= \frac{\delta \frac{s_{\mathrm{C}}}{f_{\mathrm{e}} - f_{\mathrm{s}}}}{\delta \left( 1 - \frac{f_{\mathrm{s}} s_{\mathrm{C}}}{f_{\mathrm{e}} - f_{\mathrm{s}}}\right) } \\&= \frac{s_{\mathrm{C}}}{f_{\mathrm{e}}-f_{\mathrm{s}}(1+s_{\mathrm{C}})}. \end{aligned}$$

\(\square\)

Now that we know how half lines transform under this conversion, we can derive how rays are converted from Timeline Entry Domain to Constraint Domain and back. Notice, however, that it is not enough to map the half line defining the ray via this map since we are actually interested in the subset of the domain D that is defined by this ray. As this area is also bounded by the implicit vertical line above the base point of the ray, it is clear that the image of the area of a ray under such a conversion might need to be described by multiple rays. This will be shown in various examples in Sect. 3.3.2. Furthermore it is possible that the references are such that the resulting image lies in outside of the domain D, for example \({start }\hbox {-}{} time \,{ reference }= (0, 1)\) and \({end }\hbox {-}{} time \,{ reference } = (1, 0)\) will result in a constraint interval with negative duration for time intervals of length smaller than 1. Thus a conversion of a PolygonStack P in D in any direction actually means that we map the subset of D described by P to the other domain and then intersect it with D. Therefore, these conversions are not bijections of D and by mapping forth and back we introduce so-called implicit constraints as we might remove parts of the PolygonStack. This will also be explained by some examples in Sect. 3.3.2.

3.3.1 Converting rays

The formulas (36) and (811) show how the half line of a ray is transformed. It remains to consider

  1. 1.

    cutoffs on the left and bottom, since we don’t support rays starting at e.g. \(x=-\,\infty\) or rays affecting the region below their half lines,

  2. 2.

    the special cases of \({slope } = \infty\) and

  3. 3.

    whether the region above a ray’s half line is mapped to the region above or below the transformed half ray

Regarding 1, recall that our domain D was bounded from below (as durations are non-negative) and from the left (since we consider the whole problem only after a base time \(X_0\)). Since both, timeline entries and constraint intervals, can not have negative duration, values below \(y = 0\) are considered out of scope, too. To describe the remaining two issues, one has to distinguish various cases from the different relations of \({start }\)- and \({end }\)-\({factors }\), i.e.

$$\begin{aligned} f_{\mathrm{s}} > f_{\mathrm{e}} \quad f_{\mathrm{s}} < f_{\mathrm{e}} \quad f_{\mathrm{s}} = f_{\mathrm{e}} \end{aligned}$$

and for the slopes of the considered rays

$$\begin{aligned} s = \infty \quad s > S \quad s = S \quad s < S, \end{aligned}$$

where \(S\in {\mathbb {Q}}\) denotes the critical slope, i.e., the one which is mapped to \(\infty\) [see (9), (11)]. For the conversion from Timeline Entry Domain to Constraint Domain, the critical slope is given by

$$\begin{aligned} S_{{\mathrm{T}} \rightarrow {\mathrm{C}}} = -\frac{1}{f_{\mathrm{S}}} \end{aligned}$$
(12)

and for the conversion from Constraint Domain to Timeline Entry Domain, the critical slope is given by

$$\begin{aligned} S_{{\mathrm{C}} \rightarrow {\mathrm{T}}} = \frac{f_{\mathrm{e}}}{f_{\mathrm{s}}} - 1. \end{aligned}$$
(13)

As stated in (7), we will not consider the case \(f_{\mathrm{s}} = f_{\mathrm{e}}\). However, we still need to investigate \(2 \times 4 = 8\) cases for both conversions. In the following, we pick a few examples for demonstrations.

3.3.2 Examples for conversions of rays

Fig. 4
figure 4

Conversion from Timeline Entry Domain (continuous line) to Constraint Domain (dashed line)

Figure 4 shows the conversion \({start }\hbox {-}{reference }=\left( \frac{1}{2}, 0\right)\), \({end }\hbox {-}{reference }=(1, 0)\) from Timeline Entry Domain to Constraint Domain, applied to \({\text {Ray}}\left( 1, 2, -\frac{1}{2}, d_{\text {At}}, d_{\text {Above}}\right)\) which has slope greater than the critical slope. The point \((1, 4)_{\mathrm{T}}\) in Timeline Entry Domain is mapped to \((3, 2)_{\mathrm{C}}\) in Constraint Domain; therefore, the region above the Timeline Entry Domain’s ray is mapped to the region within the dashed line and the half line starting at \((2, 1)_{\mathrm{C}}\) and passing through \((3,2)_{\mathrm{C}}\). Thus, the result of the conversion consists of two rays, the dashed line and the upper edge of the mapped region:

$$\begin{aligned}&{\text {Ray}}\left( 2,1,- \frac{1}{3}, d_{\text {At}}, d_{\text {Above}}\right) , \\&{\text {Ray}}(2,1,1, -d_{\text {At}}, -d_{\text {Above}}). \end{aligned}$$

This is an example of a PolygonStack described by a single ray in Timeline Entry Domain that is mapped to another PolygonStack in Constraint Domain that needs two rays for description.

Fig. 5
figure 5

Conversion from Constraint Domain (dashed line) to Timeline Entry Domain (continuous line)

Figure 5 shows the same conversion but from Constraint Domain to Timeline Entry Domain, applied to \({\text {Ray}}(2, 1, - \frac{1}{3}, d_{\text {At}}, d_{\text {Above}})\). The point \((2, 2)_{\mathrm{C}}\) in Constraint Domain is now mapped to \((0, 4)_{\mathrm{T}}\) in Timeline Entry Domain; therefore, the region above the Constraint Domain’s ray is mapped to the region above the continuous line and the half line starting at \((1, 2)_{\mathrm{T}}\) and passing through \((0, 4)_{\mathrm{T}}\). Unfortunately, we can not specify a ray pointing to the left; therefore, we need to start one ray at \(X_0\) [see (1)] and cancel it at \((1,2)_{\mathrm{T}}\). The result of the conversion, therefore, consists of three rays:

$$\begin{aligned}&{\text {Ray}}(X_0,Y_0,-2, 0, d_{\text {Above}}),\\&{\text {Ray}}(1,2,-2, 0, -d_{\text {Above}}),\\&{\text {Ray}}\left( 1,2,-\frac{1}{2}, d_{\text {At}}, d_{\text {Above}}\right) , \end{aligned}$$

with \(Y_0 = 2 + 2(1 - X_0)\), i.e. the ray passes \((1, 2)_{\mathrm{T}}\).

Fig. 6
figure 6

Conversion from Timeline Entry Domain to Constraint Domain with \({slope } = {critical\,slope }\). The point T is mapped to the point C together with the corresponding lines in the figure

Another example in Fig. 6 shows the conversion of a ray r with \({slope } = {critical\,slope }\): the converted region would have to start at \(y = -\infty\). To solve this, we introduce a helper-ray \({\text {Ray}}(2, 0, -2, -d_{\text {At}}, -d_{\text {Above}})\) illustrated by the dotted line. As y can not take values smaller than 0 in the PolygonStack, we know that there must exist further rays on the same line, all of which start at or above \(y=0\), such that all rays of the line sum up to 0 for all \(x>2\). Thus, the helper-rays we introduce for all of these rays on the same line within the PolygonStack sum up to 0, which means that by introducing the helper-rays, we do not modify the PolygonStack. We, therefore, can convert the ray together with its helper-ray. The result consists of four rays

$$\begin{aligned}&{\text {Ray}}(2,0,\infty ,d_{\text {At}}, d_{\text {At}}), \\&{\text {Ray}}(2,1,\infty ,-d_{\text {At}},-d_{\text {At}}), \\&{\text {Ray}}(2,0,1,d_{\text {Above}}, d_{\text {Above}})\text { and} \\&{\text {Ray}}(2, 1, 1, -d_{\text {Above}}, -d_{\text {Above}}). \end{aligned}$$
Fig. 7
figure 7

Conversion from Timeline Entry Domain to Constraint Domain with \({slope } < {critical\,slope }\)

In Fig. 7 one can see the conversion of a ray r with \(slope < critical\ slope\). Similar to the preceding case depicted in Fig. 6, we need to introduce a helper-ray. This time the result of converting the ray and its helper-ray consists of 5 rays

$$\begin{aligned}&{\text {Ray}}(2,0,1,d_{\text {Above}}, d_{\text {Above}}), \\&{\text {Ray}}(2,0,2,d_{\text {At}}- d_{\text {Above}},-d_{\text {Above}}), \\&{\text {Ray}}(3,2,2,d_{\text {Above}}- d_{\text {At}}, d_{\text {Above}}), \\&{\text {Ray}}(3, 2, 1, -d_{\text {Above}}, -d_{\text {Above}}), \\&{\text {Ray}}(3, 2, \infty , -d_{\text {At}}, 0), \end{aligned}$$

where the last one merely corrects the value at point (3, 2), which must evaluate to 0.

As Figs. 4, 5, 6 and 7 show, the conversion from Timeline Entry Domain to Constraint Domain distorts and tilts the PolygonStack. In case the slider of the end-reference is greater than the slider of the start-reference, complexity is introduced mainly due to the fact that rays can not point to the left and that they can not specify the value below their half line.

Fig. 8
figure 8

Conversion from Timeline Entry Domain to Constraint Domain with \(f_{\mathrm{e}} < f_{\mathrm{s}}\). \(H_1\), \(H_2\) and \(H_3\) are helper-rays, which are required in this case

In case the slider of the end-reference is smaller than the slider of the start-reference, however, the rays are also mirrored, see Fig. 8. This means that a ray \({\text {Ray}}\left( 1, 2, \frac{1}{2}, d_{\text {At}}, d_{\text {Above}}\right)\) with finite slope may transform to a region below a half line. However, in this case there exists a natural bound on the duration of a timeline entry to keep the constraint interval well defined. In our case, no timeline entry may have a duration greater than 6; otherwise, the constraint interval’s end-time lies before its start-time. We consider such a combination of time references as an implicit duration constraint and therefore, we can restrict our PolygonStacks to those obeying the upper bound.

We now define a helper-ray \(H_1\) which cancels the values above the upper bound, and—if applicable—two helper-rays \(H_2\) and \(H_3\) canceling H1 and the original ray at the crossing point of the upper bound and the to-be-converted ray, see the upper right corner of Fig. 8. Since we know that the PolygonStack has the ambient value above the upper bound, the helper-rays again need to sum up to 0. When mapping the ray and its helper-rays, we obtain the region below and including the dashed line, which we can represent using 4 rays

$$\begin{aligned}&{\text {Ray}}\left( 0, 2, -\frac{1}{4}, d_{\text {At}}- d_{\text {Above}}, -d_{\text {Above}}\right) , \\&{\text {Ray}}(0, 0, 0, d_{\text {Above}}, d_{\text {Above}}), \\&{\text {Ray}}(8, 0, 0, -d_{\text {Above}}, -d_{\text {Above}})\text { and} \\&{\text {Ray}}\left( 8, 0, -\frac{1}{4}, d_{\text {Above}}- d_{\text {At}}, d_{\text {Above}}\right) . \end{aligned}$$

To understand this mapping visually, you have to start with the upper bound helper-ray, which adds \(-d_{\text {Above}}\) above its half line. The half line is mapped to the x-axis and as it is mirrored, the values at and above the mapped half line must be increased by \(d_{\text {Above}}\), which, therefore, starts the region of the mapped PolygonStack. The ray itself is mapped to the dashed line and—as it is mirrored—no longer adds \(d_{\text {At}}\) and \(d_{\text {Above}}\) but instead adds \(d_{\text {At}}- d_{\text {Above}}\) and \(-d_{\text {Above}}\) to set the values on and above the half line.

Fig. 9
figure 9

Conversion from Constraint Domain to Timeline Entry Domain with \(f_{\mathrm{e}} < f_{\mathrm{s}}\)

To understand a conversion from Constraint Domain to Timeline Entry Domain as depicted in Fig. 9, one has to consider the mapping of three points: \((2,1)_{\mathrm{C}} \rightarrow (0,2)_{\mathrm{T}}\), \((2,2)_{\mathrm{C}} \rightarrow (2,0)_{\mathrm{T}}\) and \((6,2)_{\mathrm{C}} \rightarrow (6,0)_{\mathrm{T}}\). Thus, the vertical border of the ray’s affected region, i.e., the vertical line above (2, 1), is mapped to the half line starting at (0, 2) and passing through (2, 0). The dashed line is mapped to the upper border of the mapped region. The ray \({\text {Ray}}\left( 2, 1, \frac{1}{4},d_{\text {At}}, d_{\text {Above}}\right) _{\mathrm{C}}\), therefore, is mapped to

$$\begin{aligned}&{\text {Ray}}\left( 0, 2, -1, 0, d_{\text {Above}}\right) _{\mathrm{T}} \text { and}\\&{\text {Ray}}\left( 0, 2, -\frac{1}{3}, d_{\text {At}}- d_{\text {Above}}, -d_{\text {Above}}\right) _{\mathrm{T}}. \end{aligned}$$

Note that in this case, we do not have to introduce helper-rays because we can represent the result with two rays.

Fig. 10
figure 10

Conversion from Constraint Domain to Timeline Entry Domain with \(f_{\mathrm{e}} < f_{\mathrm{s}}\) for a ray with critical slope

Figure 10 shows the same conversion as preceding Fig. 9 but this time converting a \({\text {Ray}}\left( 3, 1, -\frac{1}{2}, d_{\text {At}}, d_{\text {Above}}\right)\) which has critical slope. Again, we only need two rays to represent the result of mapping the ray from Constraint Domain to Timeline Entry Domain:

$$\begin{aligned}&{\text {Ray}}(1, 2, \infty , 0, d_{\text {At}})\text { and}\\&{\text {Ray}}(1, 2, -1, 0, d_{\text {Above}}). \end{aligned}$$

Note that this time we do not need to add helper-rays either, even though the ray falls below \(y=0\). We only introduced the helper-rays to be able to represent the result as a PolygonStack and as we can represent the result of converting this ray as a PolygonStack of two rays, everything is fine.

4 Performance

This paper shows how the concept of Sliders and Offsets may be handled computationally, which is a prerequisite for usage in a planning modeling language. To see whether this method is useful, we estimate briefly the asymptotic complexity of all involved operations in the following.

4.1 Internal structure

As mentioned in Sect. 1, we want the representation of a PolygonStack as collection of rays to be unique. In the following, we present two possible solutions, both of which assume the following:

No two rays of the same PolygonStack may be equal in x, y and their slope s simultaneously.

This assumption does not impose any restriction, as two rays

$$\begin{aligned} r_1 = {\text {Ray}}(x, y, s, d^{*}_0, d^{*}_1) \\ r_2 = {\text {Ray}}(x, y, s, d^{\dagger }_0, d^{\dagger }_1) \end{aligned}$$

may be replaced by a single ray

$$\begin{aligned} r = {\text {Ray}}\left( x, y, s, d^{*}_0 + d^{\dagger }_0, d^{*}_1 + d^{\dagger }_1\right) . \end{aligned}$$

4.1.1 Ordered set of rays

A simple internal representation of a PolygonStack is a sorted set of rays, where sorting takes place in lexical order of

  1. 1.

    x (time)

  2. 2.

    y (duration)

  3. 3.

    s (slope)

Note that according to the assumption 4.1, the rays of a PolygonStack are strictly sorted by this criterion. This representation is used by [23], a suitable sweep-line algorithm for operations is described in [20].

4.1.2 Lines of rays

The sweep-line algorithm as proposed by [20] needs to consider all crossings of rays, the number of which is of the order \({\mathcal {O}}(n^2)\), where n is the number of rays. In our use case, we restrict to bounded PolygonSets. Within the underlying bounded PolygonStacks, each ray must be canceled by some ray emanating from a larger x. The ray canceling a given ray must reside on the same line as this ray. We, therefore, group the rays by lines; this way we only need to determine the crossing points of the lines instead of all rays. Sorting by lines introduces a complexity of \({\mathcal {O}}(n) \cdot C\), where C is the complexity of inserting an element into the collection of rays of the same line.

For the remaining part, we assume choosing a simple balanced tree with complexity of look up and insertion being \(C = {\mathcal {O}}(\log (n))\). The sorting therefore is of complexity \({\mathcal {O}}(n \cdot \log (n))\). However, the benefit for the calculation of crossing points for bounded PolygonStacks is in the order of \({\mathcal {O}}((\frac{n}{2})^2) ={\mathcal {O}}(n^2)\). Although the overall complexity remains \({\mathcal {O}}(n^2)\), we choose this representation for our estimation of complexity.

We define the precise representation as follows:

  1. 1.

    All rays are grouped by lines, i.e., all rays, which belong to the same line, are stored in the same group.

  2. 2.

    These groups are split into two types that are stored separately, namely

    1. (a)

      vertical lines (slope \(= \infty\)) with rays of one such line being sorted by y and

    2. (b)

      non-vertical lines (slope \(\ne \infty\)) with rays of one such line being sorted by x.

  3. 3.

    Vertical lines are sorted by their x-coordinate.

  4. 4.

    Non-vertical lines are sorted in lexical order of

    1. (a)

      the value of the group’s line at \(x=0\) and

    2. (b)

      the slope of the group’s line.

Note that all rays on the same non-vertical line must have different values for x, as they otherwise violate the assumption from Sect. 4.1. Similarly, the y-values of rays in a vertical line are all mutually distinct.

4.2 Operations

4.2.1 Addition

To add two polygon stacks G and H of size n, we need to

  1. 1.

    identify the set L of lines occurring in both G and H which has complexity \({\mathcal {O}}(n \cdot \log (n))\), and then

  2. 2.

    merge the groups of rays \(g_l \in G\) and \(h_l \in H\) which belong to the same line l. Note that merging two rays with the same x, y and slope is of order \({\mathcal {O}}(1)\). In total, we have a complexity \(\sum _{l \in L} \sum _{r \in g_l} \log (|h_l|) \le n \cdot \log (n)\), i.e., \({\mathcal {O}}(n \cdot \log (n))\).

  3. 3.

    At last, we need to create a new PolygonStack from the resulting lines which has complexity \({\mathcal {O}}(n)\).

The total complexity for this operation is, therefore, \({\mathcal {O}}(n \cdot \log (n))\).

4.2.2 Evaluation

Evaluating a polygon stack at a point (xy) may require to consider each ray in the PolygonStack. The complexity is, therefore, \({\mathcal {O}}(n)\).

4.2.3 Scan for value

Recall from Sect. 2.2.4 that a scan-line is a vertical line containing a ray’s start point or a crossing point of two rays. In a general PolygonStack of size n, the number of crossing points is of order \({\mathcal {O}}(n^2)\). To scan for a value, we need to

  1. 1.

    find all scan-lines which has complexity \({\mathcal {O}}(n^2)\) and then

  2. 2.

    for every scan-lines, determine the effect of all rays on s as well as the interval between s and the succeeding scan-line and then aggregate the corresponding rays. This has a complexity per scan-line of order \({\mathcal {O}}(n\cdot \log (n))\).

The complexity for this operation is, therefore, \({\mathcal {O}}(n^2) \cdot {\mathcal {O}}(n \cdot \log (n)) = {\mathcal {O}}(n^3 \cdot \log (n))\).

4.2.4 Find value

To find the best value according to some linear optimization problem as described in Sect. 2.2.5, we need to check the starting points and crossing points of all rays, see Lemma 1. As there are \({\mathcal {O}}(n^2)\) of these points, the complexity of this operation is \({\mathcal {O}}(n^2)\).

4.3 Polygon Stack Conversion

As every ray needs to be converted separately, the complexity of the Polygon Stack Conversion is \({\mathcal {O}}(n)\). This holds for both directions.

4.4 Comparison with resource calculation complexity

Our main use case is to allow resource constraints supporting Sliders and Offsets. We, therefore, compare the complexity of the PolygonStack operations with the complexity of other resource profile operations required by a planning algorithm.

A typical example of a resource operation is adding a modification profile. This may be to update the state-of-charge profile of a satellite’s on-board battery when adding an activity to the timeline. In general, this operation requires updating the whole resource profile, beginning at the time where the modification starts. The complexity of updating such a profile is \({\mathcal {O}}(m)\), where m is the number of profile segments, i.e., intervals where the profile has constant slope and no jumps.

According to the results in Sect. 4.2, the complexity of intersecting the results of different constraints is dominated by the operation scan for value, which has to be performed once. The polygon stack calculation, therefore, has complexity \({\mathcal {O}}(n^3 \cdot \log (n))\), where n denotes the number of rays in the PolygonStack.

The value of n, however, does not correspond to the number of segments m of a resource. Instead, it is determined by comparing a given value b with the values of a resource. Suppose, for example, that a timeline entry may be placed only in such a way, that the resource value beginning with the timeline entry is above a certain bound, e.g., there must remain sufficient energy for all future activities.Footnote 1 To represent the set of consistent timeline entries for this query, we do not have to create one ray per segment of the resource profile, because we don’t care how much energy is left, as long as there is sufficient energy left. The number of rays n, therefore, does not correspond to m but only to the number of times the profile crosses b. In practice, this value is far less than the number of segments. The \({\mathcal {O}}(n^3\cdot \log (n))\) complexity is, therefore, less problematic than one might think.

Nevertheless, it remains an important task of the planning engine to apply the constraints in a good order, such that large sections of complex resource profiles may be omitted due to restrictions of less complex constraints.

5 Summary and outlook

The main result of this paper is given by Lemmas 2 and 3. These equations allow converting timeline entry intervals into constraint intervals and back again, which forms the basis of Sliders and Offsets as introduced in Sect. 3.2 within the planning model. Although we heavily rely on PolygonStacks when describing why and how the conversion works, the same formulas should be applicable to any representation of sets of timeline entries, although the conversion’s implementation will most likely be more complex to implement.

We selected some of the 16 cases one needs to distinguish when dealing with Polygon Stack Conversion. Using these, we have been able to demonstrate how to implement the Polygon Stack Conversion and how to handle all obstacles which occur, mainly due to the non-symmetric representation of PolygonStack.

We also justified that we do not need to fear run-time issues when introducing this kind of representation. However, the theoretical complexity of \({\mathcal {O}}(n^3 \cdot \log (n))\) clearly indicates where to proceed when improving the run-time behavior: Step 2 in Sect. 4.2.3, where traversing from one interval to the next might re-use the result of the preceding interval.

Another interesting question and topic of future work is to apply the concept of Sliders and Offsets in algorithms based upon Temporal Networks, as e.g. in [2, 9, 17].