{'fraction_non_alphanumeric': 0.039074796414151784, 'fraction_numerical': 0.004858687470060905, 'mean_word_length': 4.210983002496137, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 53, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
TeSSLa: Temporal Stream-based Specification Language

Runtime verification is concerned with monitoring program traces. In particular, stream runtime verification (SRV) takes the program trace as input streams and incrementally derives output streams. SRV can check logical properties and compute temporal metrics and statistics from the trace. We present TeSSLa, a temporal stream-based specification language for SRV. TeSSLa supports timestamped events natively and is hence suitable for streams that are both sparse and fine-grained, which often occur in practice. We prove results on TeSSLa's expressiveness and compare different TeSSLa fragments to (timed) automata, thereby inheriting various decidability results. Finally, we present a monitor implementation and prove its correctness.


Introduction
The essence of software verification is to check whether a program meets its specification. Runtime verification (RV) is an applied formal technique that has been established as a complement to traditional verification techniques such as model checking [21,18]. Compared to static verification, RV considers only a single run of a system and checks whether it satisfies a property. Thus, RV can be seen as a lightweight, but formal extension to testing and debugging. RV can be applied offline to previously recorded traces or online to evaluate correctness properties at the runtime of the system under scrutiny. Typically, a property to be checked is specified as a logical formula, e.g. in (past time) LTL, and then synthesized to a monitor which can evaluate a run [19,5]. Stream runtime verification (SRV) [7], as pioneered by the language LOLA [9,14], takes a different approach by incrementally relating a set of input streams to a set of output streams. This allows not only the monitoring of correctness properties but also of quantitative measures. In this paper we introduce the novel temporal stream-based specification language TeSSLa which is tailored for SRV of cyber-physical systems, where timing is a critical issue. While traditional SRV approaches process event streams without considering timing information, TeSSLa supports timestamped events natively, which allows efficient processing of streams with sparse and fine-grained event sequences. Preliminary versions of TeSSLa have already been studied with regard to their usability to monitor trace data generated by embedded tracing units of processors [10]; how to implement stream-based monitors on hardware has been studied in theory [22] and practice [11]. These versions share the basic idea of transforming timed event streams but they did not allow for recursive equations and comprised only a set of ad-hoc operators. In this paper we define a minimal language with support for recursive definitions that allows us to obtain strong guarantees for evaluation algorithms, expressiveness results and meaningful fragments. While the practical applicability of such a language has been demonstrated by the previous papers, these papers lack a concise and clear theoretical basis and investigation. As an example for SRV, consider the following specification which checks whether a measured temperature stays within given boundaries. For every new event (measurement) on the temperature stream, new events on the derived streams low, high and unsafe are computed: low := temperature < 3 high := temperature > 8 unsafe := low ∨ high SRV is a combination of complex event processing (CEP) and traditional RV approaches: Streams are transformed into streams and there is not only one final verdict but the output is a stream of the property being evaluated at every temperature change. Furthermore, the user gets more detailed information about why an error occurred by being able to distinguish between the two separate causes low and high.
In the rest of this section we introduce the main features of TeSSLa and contrast them with related specification languages. The next section presents the language and its semantics formally, in section 3 we present several results regarding the expressiveness of TeSSLa and in section 4 we focus on comparing (fragments of) the language to variants of (timed) automata. Finally in section 5 we discuss different approaches to implement TeSSLa monitors and present our TeSSLa tool suite.
Asynchronous Streams In the previous example of traditional SRV, every stream has an event for every step of the system. TeSSLa requires the events of all streams to be in a global order, but doesn't require all streams to have simultaneous events. As a consequence, both sparse and high-frequency streams can be modeled. As cyber-physical systems often give rise to streams at unstable frequencies or continuous signals, this asynchronous setting is especially suitable. Consider as an example a ring buffer where the number of write accesses should not exceed the number of read accesses too much: Read and write events occur independently at different frequencies. The derived stream numReads (numWrites) counts the number of events of the input stream read (write). While the read and write streams contain only discrete events, the number of events can be seen as a piece-wise constant signal with the initial value of 0. The difference between the two signals is evaluated every time one of the two signals changes its value using the last known value of both signals. We call this concept signal semantics: TeSSLa handles internally only streams of discrete events, but one can express operators following signal semantics in TeSSla and hence these discrete events can be seen as those points in time where the signal changes its value. In these introductory examples operators are automatically lifted to signal semantics, which is formally introduced as the slift operator later.
Recursive Equations Like existing SRV approaches, TeSSLa relates a set of input streams to a set of output streams via mutually recursive equations, which allows self-references to the past, e.g. counting events of a stream x as in the previous example is expressed in TeSSLa as follows: count := merge(last(count, x)+1, 0) The last operator outputs the last known value of the count stream, on every event of the stream x. The base of the recursion is provided by merging with 0, which is a stream with one initial event of value 0. Since last only refers to events strictly lying in the past, the unique solution of such recursive equations can be computed incrementally (see section 2).
Time as First-Class Citizen In TeSSLa, every event has a timestamp which can be accessed via the time operator. Since every event has a timestamp which is referring to a global clock and is unique for its stream, accessing the timestamps of events serves two purposes: Accessing the global order of events by comparing timestamps and performing calculations with the timestamps. Consider e.g. the following specification which checks whether the lapse of time between two write events exceeds 5 time units and outputs the overtime if it does: In the example, the stream diff − 5 is filtered by the condition diff > 5. Note that the property violation is only reported when the delayed event happens. To report such errors as soon as possible, TeSSLa has the ability to create events at certain points in time via the delay operator. The following specification checks the same property but raises a unit event on the error stream as soon as we know that there was no write event in time: timeout := const(5)(write) error := delay(timeout , write) The delay function works as a timer, which is set to a timeout value with the first argument and reset with any event on the second argument. In the example, the function const(5)(write) maps the values of events to the constant value of 5, which is then used as timeout value. While in all the other examples the derived streams only contain events with timestamps taken from the input streams, in this example events with additional timestamps are generated. Like last, the delay operator can be used in recursive equations, for example the equation period := merge(const(5)(delay(period , unit)), 5) produces an infinite stream with an event every 5 time units. The merge is used to provide a base case for the recursion and const is used to map the value of the generated events to 5 so that they can be used as the new timeout value.
Efficient Parallel Evaluation TeSSLa's design follows two principles to allow efficient evaluation on parallel hardware: Explicit memory usage and local operator composition. If TeSSLa operates only on streams with bounded data-types of constant size, then the operators only need finite memory because every operator only needs to store at most one data value. This allows implementations on systems without random access memory, e.g. FPGAs or embedded systems. TeSSLa consists of a small set of primitive operators which can be flexibly combined. The TeSSLa semantics is defined in a way that allows a local composition of the individual operators, which can be realized via message passing without the need for global synchronization. Because of an explicit notion of progress for every stream describing how far the stream is known, local message passing is also sufficient to compute solutions for the recursive TeSSLa equations. Implementing an efficient evaluation on FPGAs is part of our EU research project COEMS 1 .
Related Work and Comparison LOLA [9,14] is a synchronous stream specification language in the following sense: Events arrive in discrete steps and for every step, all input streams provide an event and all output streams produce an event, which means that it is not suitable for handling events with arbitrary realtime timestamps arriving at variable frequencies.
The not yet formally published RTLola [15] is an extension of LOLA which introduces asynchronous streams to perform aggregations over real-time intervals. A major difference between RT-Lola and TeSSLa is that RTLola focuses on splitting input streams and aggregating over them, whereas TeSSLa provides a more general framework that in particular allows the (recursive) definition of aggregation operators while giving strict memory guarantees at the same time. Focus [8] is a formalism for the specification of stream-based systems. Their timed streams progress by discrete ticks that separate events inbetween, thereby allowing multiple events at the same timestamp. The synchronous stream programming languages Lustre [17], Esterel [6] and Signal [16], the stream specification language Copilot [24] as well as the class of functional reactive programming (FRP) languages [13] allow the description of the transformation in a linear style, i.e. an input stream is read chronologically and is thereby evaluated. TeSSLa also supports linear evaluation because there are no future-references and the number of past-references is limited by the specification size. The only complement to linear evaluation is the creation of additional events via the delay operator. Quantitative regular expressions (QREs) [2] and logics like Signal Temporal Logic (STL) [23] and Time-Frequency Logic (TFL) [12] allow the mapping from complete streams to one final verdict/quantity. They cannot generally be evaluated in a linear way. The idea used in TeSSLa of supporting signals and event streams has also been used for Timed Regular Expressions [4], but those have two explicitly different stream types, where TeSSLa internally represents signals as event streams.
Recently, synthesis of hardware-based monitors from stream specifications has become an important field: For LOLA [9] constant memory bounds for an algorithm that evaluates well-formed specifications exist and for LOLA 2.0 [14] future references must be eliminated to gain constant memory bounds. There has been work on synthesis of STL to FPGAs in different ways as well [20,25].

Formal Definition of the TeSSLa Core Language
In this section we introduce syntax and semantics of the minimal core of TeSSLa. In examples we use parametrized definitions, e.g merge(x, y) := . . . on top, which are expanded to their definitions until only core operators remain.
Preliminaries Given a partial order All variables not occuring on the left-hand side of equations are input variables. All variables on the left-hand side are output variables. We call a TeSSLa specification flat if it does not contain any nested expressions. Every specification can be represented as a flat specification by using additional variables and equations.
Semantics We define the semantics of TeSSLa in terms of an abstract time domain which only requires a total order and corresponding arithmetic operators: Definition 1. A time domain is a totally ordered semi-ring (T, 0, 1, +, ·, ≤) that is not negative, i.e. ∀ t∈T 0 ≤ t.
We extend the order on time domains to the set T ∞ = T∪{∞} with ∀ t∈T t < ∞.
Conceptually, streams are timed words that are known inclusively or exclusively up to a certain timestamp, its progress, that might be infinite. A stream might contain an infinite number of events even if its progress is finite.
We say a stream has an event with value d at time t if in its sequence d directly follows t. We say a stream is known at time t if it contains a strictly larger timestamp or a non-strictly larger timestamp followed by a data value or ⊥. Where convenient, we also see streams as functions s ∈ T → D ∪ {⊥, ?} such that s(t) = d if the stream has value d at time t, s(t) = ⊥ if it is known to have no value, and s(t) = ? otherwise. We refer to the supremum of all known timestamps of a stream as inclusive or exclusive progress, depending on whether it is itself a known timestamp. The prefix relation realises the intuition of cutting a stream at a certain point in time while keeping or removing the cutting point.
In the following, we present the denotation of a specification ϕ as a function between input streams and output streams.
Definition 3 (TeSSLa semantics). Given a specification ϕ of equations y i := e i , every e i can be interpreted as a function of input streams s 1 , . . . , s k and output streams s ′ 1 , . . . , s ′ n , that is composed of the primitive functions whose denotation is given in the rest of this section. Input variables are mapped to input streams, x i s1,...,s k ,s ′ 1 ,...,s ′ n = s i and output variables to output streams, y i s1,...,s k ,s ′ 1 ,...,s ′ n = s ′ i . Thus for fixed input streams s 1 , . . . , s k and every e i , we obtain a function e i s1,..., We now define the denotation of a specification ϕ as the least fixed-point of this function.
. . , e n s1,...,s k ) The function e 1 , . . . , e n s1,...,s k is monotonic and continuous because all primitive TeSSLa functions defined later in this section are monotonic and continuous and both properties are closed under function composition and cartesian products. (S D , ⊑) and by extension (S D1 × . . . × S Dn , ⊑ × . . . ⊑) are dcpos. By the Kleene fixed-point theorem e 1 , . . . , e n s1,...,s k has a least fixed point, which is the least upper bound of its Kleene chain.
Next we give the semantics of the primitive TeSSLa functions. The dependency of the input and output streams s 1 , . . . , s k , s ′ 1 , ..., s ′ n is assumed implicitly.

Definition 4.
Nil is a constant for the completely known stream without any events: nil = ∞ ∈ S D .
We use the unit type U = { } for streams that can carry only the single value .
Definition 5. Unit is a constant for the completely known stream with a single unit event at timestamp zero: The following functions are given by specifying two conditions: the first for positions where an output event occurs, and the second where no output event occurs. Thereby the progress of the stream is defined indirectly as the position where the output can no longer be inferred from these conditions. Definition 6. The time operator returns the stream of the timestamps of an- The lift operator lifts an n-ary function f from values to streams. The notation A 1 × . . . × A n B denotes the set of functions where all A i and B have been extended by the value ⊥.
The binary lift can naturally be extended to an n-ary lift by recursively combining two streams into a stream of tuples or partially applied functions until the final result is obtained (see Appendix A.1). Alternatively, the scheme of the binary lift can be easily extended to higher arities.
Note that while TeSSLa is defined on event streams, last realizes some essential aspects of the signal semantics: With this operator one can query the last known value of an event stream at a specific time and hence interpret the events on this stream as points where a piece-wise constant signal changes its value.
Example 3. By combining the last and the lift operators, we can now realize the signal lift semantics implicitly used in the introduction: x ′ := merge(x, last(x, y)) and y ′ := merge(y, last(y, x)). x y x ′ y ′ x + y Example 4. In order to filter an event stream with a dynamic condition, we apply the last known filter condition to the current event: Definition 10. The delay operator takes delays as its first argument. After a delay has passed, a unit event is emitted. A delay can only be set if a reset event is received via the second argument, or if an event is emitted on the output.
Formally, delay(e 1 , e 2 ) = delay( e 1 , e 2 ) where delay D ∈ S T\{0} × S D → S U is given as delay(s, s ′ ) = s ′′ such that In many applications the delay operator is used in simplified versions: In the first example of the introduction that uses the delay operator, the delay and the reset argument can be the same because the delay is used only in non-recursive equations and every new delay is a reset, too. If a periodical event pattern is generated independently from input events then the second argument can be set to unit because only an initial reset event is needed. The full complexity of the delay operator is only needed if the delay is used in recursive equations with input dependencies and ensures that the fixed-point is unique.
We can observe that all basic functions are monotonic and continuous. From the fact, that these properties are closed under composition and the smallest fixed-point is determined by the Kleene chain, we can therefore conclude: Proposition 1. The semantics of a TeSSLa specification is monotonic and continuous in the input streams.
In other words, the semantics will provide an extended result for an extended input and is therefore suited for online monitoring.
We can further observe that the pre-fixed-points on the Kleene chain have the following property: the progress only increases a finite number of times until a further event has to be appended. This is due to the basic functions that do handle progress in this way. We therefore obtain: Theorem 1. For a specification ϕ every finite prefix of ϕ (s 1 , . . . , s k ) can be computed assuming all lifted functions are computable. Assuming they are computable in O(1) steps, the prefix can be computed in O(k · |ϕ|) steps where k is the number of events over all involved streams.
Note that in case the specification contains no delay output streams cannot contain any such timestamps that did not occur already in the inputs. Further note, that fixed-points might contain infinitely many positions with data values (in case of delay) and we can thus only compute prefixes. A respective monitor would exhibit infinite outputs even for finite inputs.
Due to Proposition 1 we can reuse a previously computed fixed-point if new input events occur and hence also compute the outputs incrementally.
Well-formedness While the least fixed-point is unique it does not have to be the only fixed-point. In that case, the least fixed-point is often the stream with progress 0 or some other stream with too little progress and one would be interested in (one of) the maximal fixed-points. Since the largest fixed-points would be more difficult to compute, especially in the setting of online monitoring, we define a fragment for which a unique fixed-point exists.
Definition 11. We call a TeSSLa specification ϕ well-formed if every cycle of the dependency graph (of the flattened specification) contains at least one delayed-labelled edge. The dependency graph of a flat TeSSLa specification ϕ of equations y i := e i is the directed multi-graph G = (V, E) of nodes V = {y 1 , . . . , y n }. For every y i := e i the graph contains the edge (y i , y j ) iff y j is used in e i . We label edges corresponding to the first argument of last or delay with delayed. Because ϕ is well-formed, every e i s1,...,s k is either constant or contains at least one last or delay. The input streams s 1 , . . . , s k limit progress, i.e. the maximal timestamp produced, of e i s1,...,s k . The progress strictly increases with every step of the iteration of e 1 , . . . , e n s1,...,s k in the Kleene chain until the limit given by the input streams is reached. Every other fixed-point of e 1 , . . . , e n s1,...,s k must be an extension of the least fixedpoint, but the least fixed-point has already the maximal progress permitted by the input streams.

Expressiveness of TeSSLa
We discuss the expressiveness of four different TeSSLa fragments: TeSSLa specifications without the delay operator can only produce events with timestamps which are already included in the input streams and TeSSLa specifications with the delay operator can produce arbitrary event patterns even without any input event. On the other hand we distinguish between TeSSLa specifications which use only bounded data structures, which can only consider finitely many past events, and those with unbounded data structures which can consider infinitely many past events in the computation of new events.
To characterize functions which can be expressed in TeSSLa we define timestamp conservatism and future independence in addition to monotonicity and continuity. For a stream a ∈ S D we denote with T (a) the set of timestamps present in the stream a and for multiple streams T (a 1 , . . . , a n ) := 1≤i≤n T (a i ). For a stream a ∈ S D we denote with a| t the prefix of a with progress t.

Definition 12 (Timestamp Conservatism). We call a function
Definition 13 (Future Independence). We call a function f ∈ S D1 × . . . × S D k → S D ′ 1 × . . . × S D ′ n on streams future independent iff output events only depend on current or previous events, i.e. for input streams a ∈ S D1 × . . .× S D k and output streams Note that every TeSSLa specification is future independent because the operators last and delay are the only operators referring to events with different timestamps and they refer only to previous events. The omitted proofs of the following theorems can be found in Appendix A.2. If all data types in the TeSSLa specification ϕ are bounded,f uses a finite memory cell m, which can only store a constant number of current and previous events. Monotonicity guarantees that we can compute output events incrementally and by future independence we know that knowledge about the previous events is sufficient to derive new events. From the combination of both properties we know that it is not necessary to queue (arbitrarily large) event sequences to compute the output events. Instead one memory cell (capable of storing one element of the data domain) per delay and per last operator in the specification is sufficient. Restricting TeSSLa to bounded data types allows TeSSLa implementations on embedded systems without addressable memory because then finite memory is sufficient. Such a restricted TeSSLa specification can compute new events only based on a finite number of current and previous events.

Theorem 4 (Expressiveness of TeSSLa With Delay). Every function
can be represented as a TeSSLa specification with delay iff it is a) monotonic and continuous and b) future independent.
The proof accompanies the step-functionf with a timeout functionũ which is evaluated on every new memory state.ũ returns the timestamp of the next evaluation off , which allows arbitrary event generation. The effect ofũ can be realized using the delay operator.
We call a stream Zeno if it contains two timestamps t 1 and t 2 with infinitely many events between t 1 and t 2 . With the delay operator it is possible to construct such Zeno streams because the timeout function is not restricted in any way. By Rice's theorem it is impossible to check for an arbitrary timeout function whether it only generates non-Zeno timestamp sequences. Hence, one would need to restrict allowed timeout functions more drastically, which would restrict the possible event sequences generated by a TeSSLa specification further than necessary. For that reason we decided to include the capability to generate Zeno streams with TeSSLa. As a consequence of Theorem 4 we obtain: Corollary 1. A TeSSLa specification with multiple delays can be translated into an equivalent specification with only one delay.
TeSSLa with and without delay are closely related because TeSSLa without delay can verify the relation of given input/output streams with respect to a TeSSLa specification that uses delay. The delay is only needed to actively generate the events at specified times. In the following we denote with ϕ| y (x 1 , . . . , x k ) ∈ B the boolean function indicating whether the boolean output stream y ∈ S B of the TeSSLa specification ϕ contains only events with value true for the input streams x 1 , . . . , x k ∈ S D1 × . . . × S D k .
The above theorem follows from Theorem 3 and the fact that ϕ ′ | z is timestamp conservative, because the output stream z only contain events when any input stream contains an event. See Appendix A.2 for a constructive proof of a slightly weaker lemma.

TeSSLa Fragments and Transducers
In this section we investigate two TeSSLa fragments related to deterministic Büchi automata and timed automata, resp. We translate TeSSLa specifications to transducers, which can be seen as automata taking the in-and output of the corresponding transducer as input word. Thus by relating TeSSLa fragments to certain transducer classes, we inherit complexity and expressiveness results from the well-known automata models. Note that since one can only compare timestamps, for a TeSSLa bool -formula ϕ and two tuples of input streams S, S ′ ∈ S D1 ×. . . S Dn we have ϕ (S) = ϕ (S ′ ) iff all events in S ′ carry the same values in the same order as those in S, independent from the exact timestamps of the events. A deterministic finite state transducer (DFST) is a 5-tuple R = (Σ, Γ, Q, q 0 , δ) with input alphabet Σ, output alphabet Γ , state set Q, initial state q 0 ∈ Q and transition function δ : Q × Σ → Q × Γ . For an input word w = w 0 w 1 w 2 . . . we call a sequence s 0 To show that TeSSLa bool and DFSTs have the same expressiveness, we encode DFST words as TeSSLa bool streams and vice versa. The function α Σ (w) = S encodes a DFST word w = w 0 w 1 · · · ∈ Σ ∞ as a corresponding set of TeSSLa bool streams: For every p ∈ Σ a stream s p ∈ S exists with s p = 0d 0 1d 1 . . . ∞ ⇔ ∀i : (d i ⇔ w i = p). The function β Σ (s 1 , . . . , s k ) = w = w 0 w 1 · · · ∈ Σ ∞ encodes TeSSLa bool streams as a synchronized DFST word w over the alphabet Theorem 6. For a DFST R = (Σ, Γ, Q, q 0 , δ) there is a TeSSLa bool formula ϕ R and for a TeSSLa bool formula ϕ there is a DFST R ϕ = (Σ, Γ, Q, q 0 , δ) s.t.
Note that since the boolean transducers produce one output symbol per input symbol one could reattach the timestamps of the input streams to the output streams to preserve the exact timestamps, too.
Translating TeSSLa bool to DFST We translate every equation of the flattened specification ϕ into individual DFSTs, which are then composed into one DFST R ϕ . For every DFST the input symbols are functions from the names of the input streams to Val and the output symbols are functions from the name of the equation to Val. As discussed in the previous section, for this finite data domain we only need to consider finitely many different internal states for every equation. The transition function realizes the state changes the current output based on the current state. See Appendix A.3 for details on these transducers.
For the composition of the individual DFSTs every two R = (I → Val, O → Val, Q, q 0 , δ) and represents all equations. R A contains transitions with the same in-and output values for certain propositions which represents dependencies between the original equations. We now build the closure of this transducer which roughly resembles substituting the variables and computing the fixedpoint of the equations: Equivalence of deterministic Büchi automata is in P and because the constructed DFSTs can be represented as those we can conclude: >}, which allows checking the temporal distance of the current events of two streams. This is directly related to how clock constraints in timed automata [1,3]

work.
A timed finite state transducer (TFST) is a DFSTs with an additional set of clocks C and δ : Q × Σ × Θ(C) → Q × 2 C × Γ where Θ(C) is the set of clock constraints. A clock constraint ϑ ∈ Θ(C) is defined over the grammar ϑ ::= true | T ≤ x + c | T ≥ x + c | ¬ϑ | ϑ ∧ ϑ, where x ∈ C, and c ∈ T is a constant and T refers to the current time. δ now also takes a clock constraint and provides a set of clocks that have to be reset to T when taking this transition. A run of a TFST extends a run of a DFST with timestamps in the input and output word. An additional clock constraint has to be fulfilled to take a transitions and when taking a transitions, some clocks are set to the current time T . A more formal definition can be found in Appendix A.4.
To show that TeSSLa bool+c and DTFSTs have the same expressiveness, we again encode words as streams and vice versa, but this time α Σ and β Σ preserve the timestamps. Hence both representations are now isomorphic and we can use the inverse encoding functions for decoding: Theorem 8. For a DTFST R = (Σ, Γ, Q, q 0 , C, δ) a TeSSLa bool+c formula ϕ R exists and for a TeSSLa bool+c formula ϕ a DTFST R ϕ = (Σ, Γ, Q, q 0 , C, δ) exists: Translating DTFST to TeSSLa bool+c We reuse the translation for DFSTs with the following adjustments: We extend the stream d q,σ to d q,σ,ϑ by adding the timing constraint ϑ, which is translated by lifting the boolean combination to signal semantics and translating the constraint T ≶ x + c to time(merge{s p | p ∈ Σ}) ≶ last(time(merge(b x , unit)), merge{s p | p ∈ Σ}) + c. Also for every clock x ∈ C we add b x := merge{filter(d q,σ,ϑ , d q,σ,ϑ ) | (q, σ, ϑ, q ′ , r, γ) ∈ δ ∧ x ∈ r}.
Translating TeSSLa bool+c to DTFST The transducers from the equations in ϕ are build as before, but instead of translating equations that compare timestamps, we now translate equations of the form lift(g v )(time(a), last (time(b), a)). Besides the lift and last operators, it also contains a comparison on timestamps, which is translated using the clocks and clock constraints of the DTFSTs to remember and compare timestamps. A formalization is given in Appendix A.5. The parallel composition algorithm for DFSTs is extended by conjuncting the timing constraints of the composed transducers. Afterwards the same closure algorithm is applied. Equivalence of deterministic timed automata is PSPACEcomplete [1] and because the constructed DTFSTs can be represented as those we can conclude: Theorem 9. Equivalence of TeSSLa bool+c -formulas is PSPACE-complete.

TeSSLa Implementations and Tool Support
The TeSSLa semantics presented in this paper allows multiple implementation styles: Centralized implementations using global memory which take one synchronized input word, as well as distributed implementations using message passing which take individual asynchronous input streams.
Centralized implementations are based on the same idea as the transducers: A global step function triggers the reevaluation of all TeSSLa operators involved in the specification for one timestamp, i.e. until a delayed-labelled edge in the dependency graph is reached. This step function is either triggered by new input events or a timeout of a delay if that has a smaller timestamp. Therefore every delay can register its timeouts globally s.t. the programs main loop can check with every incoming new events if the step function must be triggered for earlier delays before handling the external input. This implementation form is well-suited for software implementations running on traditional CPUs because it minimizes the internal communication overhead. Because software implementations can use dynamic memory management, the integration of unbounded data structures is straightforward. A formalization of such transducers is given in Appendix A.6.
As motivated in the introduction, one goal of TeSSLa's design is to allow distributed, parallel implementations with finite memory, e.g. on embedded systems or FPGAs. In this scenario we neither have dynamic memory management nor can we implement a global step function. Instead, every operator in the dependency graph is translated into a computation node with a fixed-size memory cell and finite input queues storing incoming events for every dependency. This setup has already been discussed for a preliminary non-recursive version of TeSSLa in [22]. The streams used in the TeSSLa semantics presented in this paper have an explicit notion of progress, which allows the local composition of TeSSLa operators without a global synchronization. Hence every computation node can produce a new output value if at least one input queue contains a new event and all other input queues contain at least progress until the timestamp of this event. The output value is sent to the input queues of all nodes depending on this node. While recursive equations in the transducers are solved by building the closure of the transducer created by applying the parallel composition to all computation nodes, in this message passing scenario we actually implement the Kleene chain of the fixed-point defined in the TeSSLa semantics in Definition 3: Progress and values are circulated in the cyclic graph of computation nodes until the progress increases no longer, which is exactly when the fixed point is reached. Since every computation node only produces new output events if there is enough progress on every input queue, we can guarantee that the fixed point is computed before new external events are processed.
For practical evaluations of TeSSLa we implemented a TeSSLa compiler in Scala which parses the TeSSLa specification, performs static type checking and converts the specification to flat TeSSLa. Additionally we added a macro system to be able to specify more complex functions based on the basic TeSSLa operators. The macro system allows to build application-domain-specific standard libraries, which makes TeSSLa a very flexible and powerful but still convenient and easy-to-learn specification language.
Furthermore, the types of the input streams are declared explicitly and the user can specify which streams should be contained in the output. Using the macro system, implicit application of slift to functions and implicit conversion from constants to constant signals, we can write the event counting example from the introduction as follows: We combined the compiler with an interpreter written in Scala, which allows the usage of Java data structures. In order to apply TeSSLa for runtime verification we instrument the LLVM byte code of C programs and analyse this trace online with TeSSLa. This tool chain is available as a Docker container and a web IDE 2 .

Conclusion
In this paper we presented the real-time specification language TeSSLa which operates on independent, timed streams and proved that it is suitable for online monitoring. We characterized the expressiveness of TeSSLa in terms of certain classes of stream-transforming functions. We also proved the equivalence of a boolean and a timed fragment of TeSSLa to respective classes of transducers and thereby obtained that equivalence for those fragments is in P and PSPACE, resp. These results facilitate advanced optimizations and static analyses of specifications, e.g. whether such a specification can generate certain outputs. We presented an implementation based on infinite-state transducers and sketched how TeSSLa is also suitable for parallelized implementations.
Proof For a single input stream x ∈ S D and a single output stream y ∈ S D the relation between f and its iterative step functionf and the output functionõ can be described using an inductively defined function g ∈ M ∪ {⊥} × S D → S D , s.t. f (x) = y = g(⊥, x). g executesf andõ for every event of the input stream: g(m, tdw) = tõ(m ′ )g(m ′ , w) and g(m, t) = t where m ′ :=f (m, d, t). g can be naturally extended to tuples of input and output streams by synchronizing the events by their timestamps and fill in missing events with ⊥. Because f is monotonic it is sufficient to compute the output events step by step because f is future independent it is sufficient to allowf to store arbitrary information about the past events and because f is timestamp conservative it is sufficient to executef for every timestamp in the input events. Using this representation we can translate f into the following equivalent TeSSLa specification with input variables x 1 , . . . , x k and output variables y 1 , . . . , y n : The other direction follows immediately from the fact that every TeSSLa specification without delay is monotonic and continuous, timestamp conservative and future independent. Proof. By removing the timestamp conservatism requirement we need to accompany the step-functionf and the output functionõ with a timeout functionũ which is evaluated on every new memory state and can return the timestamp of the next evaluation off if no input event happens before. One timeout function is sufficient because the step-functionf can perform arbitrary computations and store arbitrary state in order to simulate multiple timeouts. The inductively de- Using this representation we can translate f into the following equivalent TeSSLa specification with input variables x 1 , . . . , x k and output variables y 1 , . . . , y n : t := time(merge(x 1 , . . . , x k , delay(d, merge(x 1 , . . . , x k )))) Constructive Delay Elimination The following lemma and its proof show constructively how to validate the delay operator in a special case of the more general Theorem 3.

Lemma 1 (Delay Elimination). For every TeSSLa specification
n with one delay operator there exists a TeSSLa specification ϕ ′ without a delay operator, which derives a boolean stream z ∈ S B , s.t. for any input streams x 1 , . . . , x k and any output streams y 1 , . . . , y n and any stream d ∈ S U we have ϕ (x 1 , . . . , x k ) = d, y 1 , . . . , y n iff ϕ ′ | z (x 1 , . . . , x k , d, y 1 , . . . , y n ) where d is the stream derived immediately through the delay operator.
Proof. We construct the validating specification ϕ ′ from the generating specification ϕ: We show how to convert the TeSSLa specification ϕ, which derives new output streams, into the TeSSLa specification ϕ ′ , which validates that the output streams were derived according to ϕ. The specification ϕ ′ derives all the streams except d in the same way as ϕ does. The stream d was derived in ϕ using the delay operator and is provided as input to ϕ ′ . The specification ϕ ′ now validates if the derived streams are equivalent to the input streams y 1 , . . . , y n . In order to check two streams for equivalence one has to assert the equivalence of the timestamps and the values separately, i.e. for every two streams y, y ′ ∈ S D we assert time(y) = time(y ′ ) ∧ y = y ′ , where = denotes the lifted equal function on D. Next we have to assert the correct derivation of d: Assuming that ϕ contains d = delay(a, r) we derive the effective delays in absolute time by distinguishing three cases: We accept the new delay on a either when the old delay is due or together with an event on r. Events on r without a new delay on a can reset the effective delay to ∞: Now we assert at all events t := merge(a, r, d) that either the delay was fulfilled by an event on d, i.e. merge(time(d), zero) = last(a ′ , t) or the delay is not due and there was no event on d, i.e. time(t) > merge(time(d), zero)∧last(a ′ , t) > time(t). The boolean stream z is derived as conjunction of all these assertions. consists of two states: s where the transducer loops for every input and applies f to the inputs to compute the output and the sink s e which is reached when one of the input streams ends: last(a, b)) has three states: It stays in the initial state as long as no event on a occurred. The other two states remember the last value that occurred on a. For every trigger event on b, the value of the current state is the output. Three additional states ensure the proper handling of inclusive and exclusive stream endings.
toDFST(z := slift(≥)(time(a), time(b)) consists of three initialization states remembering on which input streams an event already occurred. When on both streams an event occurred the transducer transits in a fourth state in which it stays until one stream ends. In this loop the output is true for every event on a and false for events occurring only on b:
x , true) = (s e , ∅, z ′ < ) δ(s v , e ⊥ ∪ a ? x , true) = (s v , ∅, z ⊥ ) δ(s v , e ′ ⊥ ∪ a ? x , true) = (s e , ∅, z ′ ⊥ ) δ(s v , e ′ y∈{<,tt,ff} ∪ a ? x , true) = (s e , ∅, z ′ < ) This transducer stays in its initial state s 0 until one stream ends: For every a it resets the clock to save the value of a. For every b it produces an output on z according to the fulfilment of the current clock constraint. The states s v and s e handle the stream endings similarly to the transducer for the last operator.

A.6 TeSSLa Transducer (TT)
Finally we introduce TeSSLa transducers as a new transducer type with the same expressiveness as full TeSSLa with arbitrary time computations, an arbitrary data domain over unbounded data structures and the delay operator, which can create new timestamps.
To resemble the delay's behaviour we define: A TeSSLa Transducer (TT) is a TFST with an extended transition function, which adds ε-transitions with clock constrains, which do not consume an input symbol, but still produce an output symbol. These have to be taken when possible but can only be taken once for every point in time. The run of a TT is extended appropriately. a run of a TT if for all i ≥ 0: σ i = ε ∧ v i , τ i |= ϑ i ∨ σ i = w j ∧ τ i = t j and τ i < τ i+1 and ∀t j : ∃τ k : t j = τ k and ∀t ∈ (τ i , τ i+1 ] : t, v i |= ϑ i ⇒ t = τ i+1 , where v i : C → R are functions mapping every clock to its current value iff s 0 = q 0 , ∀c ∈ C : v 0 (c) = 0 and for all i ≥ 0, δ(s i , σ i , ϑ i ) = (s i+1 , r i , o i ), v i+1 = v i [c ← τ i ] for all c ∈ r i and τ i , v i |= ϑ i , i.e. ϑ i resolves to true if T is replaced with τ i and every x ∈ C is replaced with the clock's current value v(x). The output of such a run is the sequence R (w) = τ 0 o 0 τ 1 o 1 τ 2 o 2 · · · ∈ (T × Γ ) ∞ .
We call a TT deterministic (or DTT for short), iff its clock constraints fulfil the same property as the ones of a deterministic TFST.
Translating TeSSLa to DTT We extend the value domain in the previous construction to arbitrary data types D and hence get Val D = {⊥, d, < ′ , ⊥ ′ , d ′ | d ∈ D}. In case of the last operator instead of the two states s x∈tf we now have (possibly infinitely many) states s x∈D . We no longer need translations for special expressions containing the time operator, but we can now directly translate the time operator itself and we add the translation of the additional delay operator. In the following we assume T always to be the corresponding τ i shown in the run before: