The Synchronous Data Flow LUSTRE

NICHOLAS HALBWACHS, PAUL CASPI, PASCAL RAYMOND, AND DANIEL PILAUD Invited Paper

This paper describes the language LUSTRE which is a data flow Parallelism: First, their design must take into account synchronous language, designed for programming reactive sys- the parallel interaction between the system and its tems-uch as automatic control and monitoring systemsas well environment. Second, their implementation is quite as for describing hardware. The data flow aspect of LUSTRE makes it very close to usual description tools in these domains (- often distributed for reasons of performance, fault diagrams, networks of operators, dynamical sample-systems, etc.), tolerance, and functionality (communication protocols and its synchronous interpretation makes it well suited for han- for instance). Moreover, it may be easier to imagine dling time in programs. Moreover, this synchronous interpretation a system as comprised of parallel modules cooperat- allows it to be compiled into an efficient sequential program. ing to achieve a given behavior, even if it is to be Finally, the LUSTRE formalism is very similar to temporal logics. This allows the language to be used for both writing programs implemented in a centralized way. and expressing program properties, which results in an original Time constraints: These include input frequencies and program verification methodology. input-output response times. As said above, these constraints are induced by the environment, and should I. INTRODUCTION be imperatively satisfied. Therefore, these should be specified, taken into account in the design, and verified A. Reactive Systems as an important item of the system’s correctness. Reactive systems have been defined as computing sys- Dependability: Most of these systems are highly criti- tems which continuously interact with a given physical cal ones, and this may be their most important feature. environment, when this environment is unable to synchro- Just think of a design error in a nuclear plant control nize logically with the system (for instance it cannot wait). system, and in a commercial aircraft flight control sys- Response times of the system must then meet requirements tem! This domain of application requires very careful induced by the environment. This class of systems has design and verification methods and it may be one been proposed [6], [21] so as to distinguish them from of the domains where formal methods should be used with higher priority; design methods and tools that transformational systems-i.e., classical programs whose data are available at their beginning, and which provide support formal methods should be chosen even if these results when terminating-and from interactive systems imply certain limitations. which interact continuously with environments that possess synchronization capabilities (for instance operating sys- B. The Synchronous Approach tems). Reactive systems apply mainly to automatic In our opinion, most programming tools used in designing control and monitoring, and signal processing,-but also to reactive systems are not satisfactory. Clearly, assembly systems such as communication protocols and man-machine languages do not, though they are widely used for rea- interfaces when required response times are very small. sons of code efficiency. Other methods include the use Generally, these systems share some important features: of classical languages for programming sequential tasks Manuscript received September 20, 1990; revised March 2, 1991. This that cooperate and synchronize using services provided work was supported in part by the French Ministhe de la Recherche within contract “Informatique 88,” and in part by PRC C3 (CNRS) IMAGLGI- by a real-time operating system, and the use of parallel Grenoble -Grenoble, languages that provide their own real-time communication N. Halbwachs, P. Caspi, and P. Raymond are with the Laboratoire de services. Even the later, which seems more promising, has Genie Informatique, Institut IMAG, 38041 Grenoble, Cedex, France. D. Pilaud is with VERILOG, 38330 Montbonnot, St. Martin, France. been criticized [6] since the services being provided are low IEEE Log Number 9102318. level; this does not allow programs to be easily designed

0018-9219/91$01.00 0 1991 IEEE

PROCEEDINGS OF THE IEEE, VOL 79, NO. 9, SEPTEMBER 1991 1305

~~ ~-~ - ~~ __ properties. Also, reuse is made easier, which is an

x = 2.Y + 2 interesting feature for reliable programming concerns. It is a parallel model, where any sequencing and w=x+1 + +&--gjysynchronization constraints arise from data dependen- cies. This is a nice feature which allows the natural Fig. 1. A data flow description and its associated equations. derivation of parallel implementations. It is also inter- esting to notice that, in the above domain, people were accustomed to parallelism, at much earlier times than and validated, while appears to be rather expensive at run in other areas in computer science. time. Synchronous languages have been recently proposed in order to deal with these problems: such languages D. Synchronous Data Flow provide “idealized” primitives allowing programmers to It may thus seem appealing to develop a data flow think of their programs as reacting instantaneously to approach to . However, up until now external events. Thus each internal event of a program data flow has been thought of as essentially asynchronous, takes place at a known time with respect to the history of whereas a synchronous approach seems necessary to tackle external events. This feature, together with the limitation to the problem of time, for instance by relating time with the deterministic constructs, results in deterministic programs index of data in flows. This was the first concern of the from both functional and temporal points of view. In LUSTRE[14] project which is reported here. It resulted in practice, the synchronous hypothesis amounts to assuming proposing primitives and structures which restrict data flow that the program is able to react to an external event, before systems to only those that can be implemented as bounded any further event occurs. If it is possible to check that this memory automata-like programs in the sense of ESTEREL. hypothesis holds for given program and environment, then The language, together with programming examples, will this ideal behavior represents a sensible abstraction. The be presented in Section 11. Then compiling and efficient pioneering work on ESTERELhas led to propose a general code generation matters will be discussed in Section 111. structure for the object code of synchronous programs: The second main concern of the project is to take a finite automaton whose transition consists of executing advantage of the approach in developing techniques of a linear piece of code and corresponds to an elementary formal verification (Section IV). The idea is to consider reaction of the program. Since the transition code has no LUSTREas a specification language as well, thanks to its loop, its execution time can be quite accurately evaluated declarative aspect. It is then shown that the same on a given machine; this enables us to accurately bound the can be used as a tool for verifying program correctness with reaction time of the program, thus allowing the synchronous respect to such specifications. Section V presents several hypothesis to be checked. Synchronous languages include other current activities of the project, related to hardware (see this issue) ESTEREL,SIGNAL, STATECHARTS, SML, and and distributed implementations. Finally comparisons with several hardware description languages [ 101. existing approaches are discussed.

C. The Data Flow Approach 11. THE LUSTRELANGUAGE One method for reliable programming is to use high level languages, i.e., languages that allow a natural expression A. Flaws and Clocks of problems as programs. Within the domain of reactive In LUSTREany variable and expression denotes a flow, programming, many people are used with automatic control i.e., a pair made of and electronic circuits; traditionally, these people model a possibly infinite sequence of values of a given type; their systems by means of networks of operators transform- a clock, representing a sequence of times. ing flows of data-gates, switches, analog devices-and A flow takes the nth value of its sequence of values at the from a higher level, by means of boolean functions and nth time of its clock. Any program, or piece of program transfer functions with block-diagram structures, and finally has a cyclic behavior, and that cycle defines a sequence by means of systems of dynamical equations which capture of times which is called the basic clock of the program: a the behavior of these networks. Such formalisms look quite flow whose clock is the basic clock takes its nth value at the similar to what computer scientists call “data flow” systems nth execution cycle of the program. Other, slower, clocks [25], [26] (cf. Fig. 1). can be defined, thanks to boolean-valued flows: the clock Therefore data flow can be considered as a high level par- defined by a boolean flow is the sequence of times at which adigm in that field. Furthermore, as a basis of a high level the flow takes the value true. For instance Table 1 displays programming language, it possesses several advantages. the time-scales defined by a flow whose clock is the basic It is a functional model with its subsequent mathemat- clock, and by a flow C’ whose clock is defined by C. ical cleanness, and particularly with no complex side It should be noticed that the clock concept is not nec- effects. This makes it well adapted to formal verifica- essarily bound to physical time. As a matter of fact, the tion and safe program transformation, since functional basic clock should be considered as setting the minimal relations over data flows may be seen as time invariant “grain” of time within which a program cannot discriminate

1306 PROCEEDINGS OF THE IEEE, VOL. 79. NO. 9, SEPTEMBER 1991 Table 1 Boolean Flows and Clocks Table 2 Sampling and Interpolating

basic B false true false true false false true true time- 1 2 3 4 5 6 7 8 scale X X1 X2 X3 I4 X5 X6 27

1 t; false tr; tr; false try false try Y = X when X4 27 I8 i B time- scale 1; 1 false tr; false tr; tr; time- the expression scale if X > 0 then Y + 1 else 0 external events, and which corresponds to its response time. If “real time” is required, it can be implemented is a flow on the basic clock whose nth value for any as an input boolean flow: for instance a flow whose true integer n is: value indicates the occurrence of a “millisecond” signal. This point of view provides a multiform concept of time: if Z, > 0 then y, + 1 else 0. “millisecond” becomes a time-scale of the program among others. Besides these operators, LUSTREhas four more which are called “temporal” operators, and which operate specifically on flows: B. Variables, Equations, Expressions, Assertions pre (“previous”) acts as a memory: if (el, e2, . . . , e,, . . .) is the sequence of values of expression E, pre (E) Variables should be declared with their types, and vari- has the same clock as E, and its sequence of values ables which do not correspond to inputs should be given is (nil, el, e2,. . . , e,-1,. . .), where nil represents an one and only one definition, in the form of equations. These undefined value denoting an uninitialized memory. are considered in a mathematical sense: the equation = “X -> (“followed by”): if E and F are expressions E ;” defines variable X as being identical to expression E. with the same clock, with respective sequences Both have the same sequence of values and clock. However (e1,e2.. . . ,e,, . . .) and (f1, fi,. . . , f,,. . .), then such an equation is oriented in the sense that it defines E- >F is an expression with the same clock as E and F, X. The way it is used in other equations cannot give it and whose sequence is (el, f2, f3. . . , f,, . . .). In other more properties than those which arise from its definition. words, E->F is always equal to F, but at the first time This provides one important principle of the language, the of its clock. substitutionprinciple: X can be substituted to E anywhere in the program and conversely. As a consequence, equations Table 2 shows the effect of the last two operators: can be written in any order, and extra variables can be when “samples” an expression according to a slower created so as to give names to subexpressions, without clock: if E is an expression and B is a boolean changing the meaning of the program. LUSTREhas only expression with the same clock, then E when B is few elementary basic types: boolean, integer, real, and one an expression whose clock is defined by B, and whose type constructor: tuple. However, complex types can be sequence is extracted from the one of E by keeping imported from a host language and handled as abstract types only those values of indexes corresponding to true (A similar mechanism exists in ESTEREL). values in the sequence of B. In other words, it is the Constants are those of the basic types and those imported sequence of values of E when B is true. from the host language (for instance constants of imported current “interpolates” an expression on the clock types). Corresponding flows have constant sequences of immediately faster than its own. Let E be an expression values and their clock is the basic one. Usual operators whose clock is not the basic one, and let B be the over basic types are available (arithmetic: +, -, * , / , boolean expression defining this clock. Then cur- div , mod ; boolean: and, or , not ; relational: = , rent E has the same clock C that B has, and its < , < =, >, >= ; conditional: if then else) and value at any time of this clock C, is the value of E at functions can be imported from the host language. These the last time when B was true. are called data operators and only operate on operands Besides being made of equations, the body of a LUSTRE sharing the same clock; they operate pointwise on the program may contain assertions. These generalize equa- sequences of values of their operands. For instance, if X and tions and consist of boolean expressions that should be Y are on the basic clock, and their sequences of values are always true. Their primary use is to give to the compiler respectively (z~:Q,.. . ,z,, . . .) and (y1,y2,. . . ,ynr...), indications in order to optimize the code when the environ-

HALBWACHS et a1 SYNCHRONOUS DATAFLOW PROGRAMMING LANGUAGE LUSTRE 1307

~ .- ~ ____- ~- Such a node can be functionally instanced in any expres- sion. For instance, n even = COUNTER(0,2,false); 1 s- modulo5 = COUNTER(O,l,pre(modulo5)=4);

define the sequence of even numbers and the cyclic sequence of modulo 5 numbers, over the basic clock. Similarly, if gamma is an acceleration expressed in meter/secon,d2,and its clock’s rate is onepersecond, one could have Fig. 2. Counter network. speed = COUNTER(O,gamma,false); position = COUNTER(O,speed,false); ment of the program possesses some known properties (see Section 111-D). For instance, if we know that two input According to the substitution principle, this is equivalent to: events represented by boolean variables x and y never occur at the same time, we shall write: position = COUNTER(O,COUNTER(O,gamma, false), assert not (x and y); false);

Similarly, the assertion A node may have several outputs; in that case, the output is a tuple. For instance, assert (true -> not(x and pre(x))); node D-INTEGRATOR(gamma: int) returns says that event x never occurs twice in a row. Note the (speed,position:int); initialization to true, which prevents the occurrence of let value nil, which is forbidden in assertions, clocks, and speed = COUNTER(O,gamma,false); output sequences (cf. Section 111-A). Besides their use position = COUNTER(O,speed,false); in code optimization, assertions play a important role in tel. program verification (cf. Section IV). is instanced as

(v,x) = D-INTEGRATOR(g); C. Program Structure A LUSTREsystem of equations can be represented graph- Concerning clocks, the basic clock of a node is defined ically as a network of operators. For instance, the equation: by its inputs, so as to be consistent with the data flow point of view. For instance, expression: n = 0 -> pre(n) + 1; COUNTER( (O,l,false) when B ) which defines a counter of basic clock cycles, corresponds to the network of Fig. 2. This naturally suggests some counts only when B is true. In the example, operator when notion of subroutine: a subnetwork can be encapsulated as applies to the tuple ( 0,1, false).l Table 3 shows the a new reusable operator which is called a node. A node result of the expression, and the difference with expression declaration consists of an interface specification-providing (COUNTER(0, 1 ,false) ) when B , where sampling input and output parameters with their types and possibly applies to the output of the node instead of its inputs. their clocks-optional internal variables declarations, and This example also stresses the interest of clocks in reuse; a body made of equations and assertions defining outputs had clocks not been available, the only way of getting the and internal variables as a function of inputs. same effect would have required to modify the node by For instance, the following node defines a general pur- adding a “do-nothing” input. pose counter, having as inputs an initial-and-reset value, an A node may admit input parameters with distinct clocks. increment value, and a reset event: Then the faster one is the basic clock of the node, and all other clocks must be in the input declaration list. In the node COUNTER(va1-init, Val-incr: int; following example: reset: bool) returns (n: int); node N (mil1isecond:bool; (x:int ; let y :bool ) n = Val-init -> if reset then when millisecond) returns... Val-init else pre(n) + Val-incr; ’This is equivalent to COUNTER( 0 when B, 1 when B, false tel. when B)

1308 PROCEEDINGS OF THE IEEE, VOL. 79, NO. 9, SEPTEMBER 1991 Table 3 Nodes and Clocks 3) Logical Systems: From the previous discussion, data flow programs of signal processing systems are very close B true false true false true to their specification in terms of systems of dynamical ( 0,1, false ) (0,lfulse) (0,1false) (0, lfalse) equations. However, many systems have an important log- when B ical component, and some of them, for instance monitoring systems, are essentially logical systems. Such systems are COUNTER 0 1 2 ((O,l,false) most often described in terms of automata, parallel au- when B) tomata (STATECHARTSfor instance), and Petri nets, i.e., imperative formalisms which describe states and transitions COUNTER 0 1 3 3 4 ( 0,1, false) between states. The question about the adequacy of data flow paradigms to provide easy descriptions of such sys- (COUNTER 0 2 4 tems should therefore be carefully checked. The following (O,l,false)) when B examples are intended to show that these paradigms may allow easy, incremental and modular descriptions of logical systems. In this subsection we shall consider three versions of a “watchdog,” i.e., a device that monitors response times. the basic clock of the node is the one of millisec- The first version receives three events: set and reset ond, and the clock of x and y is the one defined by commands, and deadline occurrence. The output is an millisecond. alarm that must be raised whenever a deadline occurs Outputs of a node may have clocks different from its and the last received command was a set. basic clock. Then these clocks should be visible from the As usual, events are represented by boolean variables outside of the node. Note also that these clocks are certainly whose value true denotes the presence of an event. The slower than the basic one. watchdog will be a LUSTREnode having three boolean inputs set,reset and deadline and emitting a boolean D. Some Programming Examples output alarm. As the order of equations is unimportant, we begin by defining the output: is true when 1) Linear Systems: Translating sampled linear systems alarm into LUSTREprograms is quite an obvious task: if systems deadline is true and the last true command is set. Let are expressed in z-transform equations, it amounts to trans- is-set be a local boolean variable expressing the latter condition. Then, we can write: lating the z-l operator into 0.0 -> pre ( ). For instance, consider the second-order filter: alarm = deadline and is-set; az2 + bz + c H(z)= z2 + dz + e ‘ It remains to define is-set,which becomes true any time set is true, and false any time reset is true. Initially, The output y = H(z)z can be written: it is true if set is true and false otherwise:

y = ax + (b:c - ciy)z-l + (ex - ey)z-’ is-set = set -> if set then true else if and yields the following program: reset then false else pre(is-set); const afblc,dfe:real. We can furthermore assume that set and reset commands node SECOND-ORDER(x: real) returns never take place at the same time, which can be expressed (y: real); by an assertion. The full program is: var u,v: real; let node WD1 (set, reset, deadline: bool) y = a*x + (0.->pre(u)); returns (alarm: bool); U = b*x - d*y + (0.->pre(v)); var is-set: bool; v = c*x -e*y; let tel. alarm = deadline and is-set; is-set = set -> if set then true Furthermore, clocks allow an easy extension to multiply else if reset then sampled systems. false else pre(is-set); ( ; 2) Nonlinear and Time-Varying Systems: Letting a b c I d e assert not set and reset) be parameters of the SECOND-ORDER node, instead of constants, yields a time-varying filter. Nonlinear systems are also easy to describe. For instance: Let us consider now a second version which receives the same commands, but raises the alarm when no reset y = rho c cos(theta0- > pre(theta)); has occurred for a given time since the last set, this

HALBWACHS et al.: SYNCHRONOUS DATAFLOW PROGRAMMING LANGUAGE LUSTRE 1309 time being given as a number of basic clock cycles. This 111. THE LUSTRE COMPILER new program reuses node WD1, by providing it with an Let us describe now the main techniques used in the appropriate deadline parameter: on reception of a set LUSTRE-v2compiler [30]. This prototype compiler has been event, a register is initialized, which is then decremented. written in Le-Lisp by John Plaice. Deadline occurs when the register value reaches zero; it is built from a general purpose node EDGE which returns true A. Static Verifications at each rising edge of its input: Static well-formedness checking is clearly an important issue within the framework of reliable programming, and node EDGE (b: bool) returns (edge: bool); aims at avoiding the overhead of dynamic checks at run let time. Besides classical type checking, the main checks = -> edge false (b and not pre(b)); performed by the compiler are: tel. Definition checking: any local and output variable should have one and only one equational definition. node WD2 (set, reset: bool; delay: int) returns (alarm: bool); Absence of recursive node call: in view of obtaining var remain: int; deadline: bool; automata-like executable programs, LUSTREallows up to now only static networks to be described. The let problem of structuring recursive calls so that the above alarm = WDl(set, reset, deadline); property is maintained, has not yet been investigated. deadline = false -> EDGE(remain = 0); remain = if set then delay Clock consistency, which will be more intensively else if pre(remain)>O discussed in the following. then pre(remain)-1 Absence of uninitialized expressions (yielding nil val- else pre(remain); ues). Such expressions are accepted as far as these do not concern clocks, outputs, and assertions. tel. Absence of cyclic definitions: any cycle in the network Assume now that the delay is expressed according to should contain at least one pre operator. In the sense a given time-scale, i.e., as a number of occurrences of an of [25]an equation such that: X = 3*X + 1 has a event time-unit.We just have to call WD2 with an appro- meaning which is the least solution with respect to the priate clock: WD2 must catch any time units time-unit, prefix ordering of sequences; in this case, the solution any commands, and must be properly initialized so that for X is the empty sequence, and it can be interpreted alarm never yields nil: as a deadlock. It is therefore rejected. Note also that LUSTREalso rejects structural deadlocks which are not node WD3 (set, reset, time-unit: bool; true ones, such that: delay: int) returns (alarm: bool); X = if C the Y else 2; var clock: bool; Y = if C then 2 else X; let alarm = current(WD2((set,reset,delay) The reason is that the analysis of such networks is when clock)); undecidable, in general. clock = true -> (set or reset or Let us discuss now the clock calculus which represents time-unit); an original aspect of LUSTREwith respect to data flow tel. languages. The following program illustrates the reason for such a calculus: Coming back to the question raised at the beginning of b = true-> not pre b; the section, we can see that programs have been written y = x + (x when b); without referring to transitions between states, but rather by describing states in terms of state variables, and by stating In the second equation, a data operator combines two the strongest invariant property of each state variable. Then, flows of distinct clocks. According to standard data flow all state variables will evolve in parallel, thus recreating the philosophy, such a program has a meaning. However, it global state of the system. It has been shown in [8] that any is easy to see that the computation of the 2nth value of finite state machine can be described by a boolean LUSTRE y needs both the 2nth and the nth values of 2. Since a program. reactive system may be assumed to run for ever, its required 4) Mixed Logical and Signal Processing Systems: Finally, memory will certainly overflow. Such a program could mixing signal processing and logical systems is quite an not be compiled into a bounded memory object code, not easy task: Signal processing parts provide logical ones to speak of the physical incoherence consisting of adding with boolean expressions by using relational operators, something at time n with something at time 2n. and conversely, logical components control signal flows by The clock calculus consists of associating a clock with means of conditional operators: if then else, when each expression of the program, and of checking that any and current. operator applies to appropriately clocked operands:

1310 PROCEEDINGS OF THE IEEE, VOL. 79, NO. 9, SEPTEMBER 1991 variables are given an unique name (so as to distinguish that node call from other instances of the same node) and then the called node body is inserted into the calling node body. The code generation step will then start from a “flat” node which does not call any other node.3 Fig. 3. A cyclic call. C. Single-Loop Code An obvious way of associating an imperative program any primitive operator with more than one argument with a LUSTREnode consists of constructing an infinite applies to operands sharing the “same” clock; loop whose body implements the inputs to outputs trans- the clock of any operand of a current operator is formation performed at any basic cycle of the node. This not the basic clock of the node it belongs to;2 is done by: the clocks of a node operands should obey the clocks choosing variables to be computed (the output ones requirements stated in the node definition header. and the least possible number of local ones, which Let us define here what we mean by “the same clock.” implement either memories or temporary buffers); Ideally, it could mean the same boolean flow, but this may defining the actions which update these variables; require semantic analysis which are undecidable in general. choosing an ordering of these actions, according to Thus the compiler uses a more restricted notion of equality: the dependencies between variables induced by the two boolean expressions define the same clock if and only if network structure of the node. these can be unified by means of syntactical substitutions. As an example, let us consider a modified version of the Consider the example: watchdog WD3: x = a when (y > z); node WD4 (set,reset,u-tps:bool; delay: y = b+c; int) returns (a1arm:bool; var is-set: bool; remain:int; U = d when (b+c > z); v = e when (z < y); let alarm = is-set and (remain = 0) and x and U share the same clock, which is considered to be pre(remain) > 0; distinct from the clock of v. The rules of the clock calculus are formally described in is- set = false -> if set the true else if reset then 1141, 1301. false else pre(is-set); B. Node Expansion remain = 0 -> if set then delay The LUSTREcompiler produces purely sequential code. else if u-tps and This raises the question of compiling separated nodes which pre(remain) > 0 are used in other nodes. The following example shows this then cannot be easily done for LUSTRE: pre(remain)-1 else pre(remain); node two-copies (a, b: int) returns assert not(set and reset); (x, y: int); tel. let x = a ; y = b ; end. The single-loop body, which is executed at each program Clearly, there are two possible sequential codes for reaction. looks like: a basic cycle of this node, either x:=a;y:=b; or y:=b;x:=a; if -init then % first cycle % But the choice between those two programs may depend is-set := false; remain := 0; on the way the node is used within another node; for alarm :=false; -init := false instance: else % other cycles % (xly)= two-copies(a,x) if set then is-set:= true; remain:= delay corresponding to Fig. 3. In this case, only the former else program is correct. if reset then is_set:= false endif; Thus before compiling a program, the compiler first ex- if u-tps and (-pre-remain>O) then pands recursively all the nodes called by that program, i.e., remain := -pre-remain-1 endif; formal parameters are substituted with actual ones, local endif

21n contrast with SIGNAL,LUSTRE does not allow basic clock time 3However, we shall see in Section V-A that some separate compiling intervals to be split into smaller ones. technique can also apply.

HALBWACHS et al., SYNCHRONOUS DATAFLOW PROGRAMMING LANGUAGE LUSTRE 1311

~ ~- ~~ ___~ alarm := is-set and (remain=O) and generating state values and transitions, so as to avoid (-pre-remain > 0); generating useless items). The result is a finite state au- endif tomaton, whose transitions are labeled with the code of the write(a1arm); -pre-remain := remain; corresponding reaction. State variables can be chosen in several ways among the 1) Remarks: following: The compiler has defined auxiliary variables: the vari- boolean expressions resulting from pre and current able Anit-which is assumed to be initialized to true operators, and is used to implement the operator ->-and the auxiliary variables like Lnit-C,associated with some memory variable -pre-remain.Note that the expres- clock C whose value is true at the first clock cycle sion pre( is-set) did not result in the creation of and then false, and which allow the evaluation of -> a memory variable since the compiler found a way to operators. avoid it. This control synthesis is illustrated on the watchdog exam- Although it is easy to find an ordering of actions ple WD4 (cf. Section 111-C): The chosen state variables are which meets the dependency relations between vari- pre ( is-set ) and -init.Then: ables (static checks described above ensure that such The first cycle yields pre ( is-set ) =nil and an order exists), the choice of a “good” order is quite -init=true. Let So be this initial state. Since difficult: particularly, the order according to which in this state, the value of all conditional statements are opened and closed is critical -init=true -> operators is the one of their first operand. with respect to code length. Thus and Elementary The code speed could be improved. Note for instance is-set=false, remain=O. boolean calculus yields Further- that at any cycle the program tests whether this is the alarm=f alse. more, since evaluates to false, this will be first one or not, and this is particularly awkward. A is-set the value of at the next state. The solution consists of using more complex control struc- pre( is-set) next state, is then and tures than the single-loop structure. This is discussed 5’1, pre(is-set)=false in the following section. -init=false. State So code looks like:

SO : remain := 0; alarm := false; D.Automaton-Like Code pre-remain := remain; The search for more complex control structures is bor- goto s1; rowed from the compiling technique of ESTERELand is based on the following remarks: The classical concept of control of imperative pro- In state SI, since pre(is-set) value is false, grams is represented in LUSTREby means of boolean is-set evaluates to true if and only if the in- variables acting over conditional and clock handling put set value is true. Let Sz be the state where operators. pre ( is-set ) is true and -init is false. The code If a condition or a clock depends on values of a boolean for state SIis: variable computed at previous cycles (by means of an expression like pre(B) or current(B)) the code S1 : if set then of the actual cycle could be made simpler if that remain := delay; value could be assumed to be known. One could then alarm := (remain = 0) and distinguish the code to be executed according to that (pre-remain > 0); value. pre-remain := remain; The synthesis of the control structure consists of choosing goto s2; a set of state variables of boolean type, whose values are else expected to influence the code of future cycles. This set of remain := if u-tps and variables is called the state of the program and it takes only pre-remain > 0 a finite set of values. For each possible value of the state, then pre-remain-1 one defines the sequential code which would be executed else pre-remain; during a cycle if the state of the variables had the above alarm := false; values just before the execution of the cycle. Hence, starting pre-remain := remain; from a given state and executing the corresponding code goto s1; would result in computing the next state, and be ready for endif the execution of the next cycle. Finally, a static reachability analysis can be performed so as to delete state values and transitions which cannot be reached from the initial state The code of state S2 (pre(is-set) is true and (As a matter of fact, this reachability analysis is done while Anit is false), is as follows:

1312 PROCEEDINGS OF THE IEEE, VOL. 79, NO. 9, SEPTEMBER 1991 as state variables, and any branch yielding a false assertion is deleted. A state whose total code has been deleted is then declared unreachable, and branches already computed which lead to that state are recur- sively deleted. It should be noticed that assertions may increase the number of state variables and reachable set states, as well as increase code length by inducing extra tests. In contrast with ESTEREL automata, the obtained Fig. 4. The watchdog control automaton. LUSTREautomata are often far from being minimal (this question will be further discussed in Section V- A). This entails a need for minimization. S2 : if set then remain := delay; E. The ESTERELILUSTRE Environment alarm := (remain = 0) and Automata produced by the LUSTRE compiler are ex- (pre-remain pressed in the OC format [32], which is also used by the > 0); ESTERELcompiler. Several common tools take this format pre-remain := remain; as input: goto s2; . Code generators: Translators toward C, Le-Lisp, and else ADA languages have been designed by the ESTEREL if reset then team. They produce the procedure which implements remain := if u-tps and the code corresponding to a transition of the automa- pre-remain > 0 then tion. pre-remain-1 . Automaton minimizer: The ALDEBARAN[ 161 mini- else pre-remain; mizer has been interfaced with OC. It allows minimal alarm := false; equivalent automata to be obtained in OC, and this is pre-remain := remain; particularly useful in the case of LUSTRE. goto s1; Interfaces with proof tools: Automata are a common else basic model in many analysis and verification tools remain := if u-tps and for parallel systems. It was therefore appealing to pre-remain > 0 experiment with the use of such tools operating on Oc then pre-remain-1 automata. Thus OC has been interfaced with AUTO else pre-remain; [39]. Some experiments have also been performed alarm := (remain = 0) and with EMC [13] and XESAR [36]. However, we shall (pre-remain > 0); see in Section IV other proof techniques which apply pre-remain := remain; specifically to LUSTRE. goto s2; . Display tools: The OC language has been designed endif for internal code representation, and it thus lacks of endif readability. For checks and debugging purposes, trans- All reachable states being processed, this ends the code lators toward readable representations, and graphic generation. Figure 4 displays the resulting automaton. display based on the AUTOGRAPH[34] code, have been I) Remarks: developed. The obtained transition codes are much simpler than the single-loop code, particularly for SOand 5’1 codes. IV. VERIFICATION This reduction may be even more impressive for larger As noted in the introduction, reactive systems often programs. concern critical applications, and thus program verification In contrast, the overall length of the code may become is a key issue. However, many practitioners in the field very large. That is why, in practice, an action code are skeptical with the use of formal verification methods, table is built which uniquely identifies actions that and convincing arguments need to be provided in order to may belong to several transitions, and transition codes support our claim that indeed, such methods are of practical refer to actions by means of their indexes in the table. interest. This is the object of the following discussion. Boolean expressions depending on non boolean vari- The research on program verification which started in the ables, which are needed for computing state variables early seventies intended to provide complete proofs of (integer comparison for instance) are handled as inputs very general programs. Though this work has led to im- by means of tests on their value. portant contributions concerning programming techniques This technique allows assertions to be fully taken into and language design, one should admit that its use in account. Assertions are computed in the same way practice is very limited. However, our goal concerning

1313 HALBWACHS et a1 SYNCHRONOUS DATAFLOW PROGRAMMING LANGUAGE LUSTRE

~~ ~------reactive systems may be less ambitious. Almost always, 0 LUSTREcan be considered as a subset of a temporal the safety of a critical application does not depend on logic [8], [29]. Our proposal is then to express any the total correctness of its control program, but rather on temporal property P by a boolean expression B, such an often small set of properties that the program should that P holds if and only if enpresqion B is always trrze fulfill. For instance, the occurrence of a critical situation during any execution path of the program. According should raise an alarm within a given delay. From our to [8], any safety property can be expressed in such experience, the proof of such properties can often be a way. handled within the framework of simple decidable theories, . The above proposal is easily implementable by using as these properties seldom depend on numerical relations the assertion mechanism of LUSTRE:LUSTRE assertions and computations. Furthermore, most of these properties are already a means of expressing properties of a are “safety” properties which state that a given situation program’s environment. should never appear, or that a given statement should . The use of a programming language for expressing always hold, in contrast with “liveness” properties which both programs and their properties is interesting since state that a given situation should eventually appear in the all the structuring facilities of the language become future. For instance, a relevant question is not that a train available for the sake of readability and expressiveness. will eventually stop, but that it never crosses a red light. For instance, as we will show, the node concept will This is an important remark as proof techniques for safety allow the user to define its own temporal operators. properties are known to be much simpler than for liveness Let us show here how some useful nontrivial temporal properties: operators can be expressed as LUSTREnodes. Consider the A safety property can be verified by simply check- following property: ing properties of reachable states, without taking into “any occurrence of a critical situation must be account the transition relation (it is used only for followed by an alarm within a five seconds delay”. constructing the reachable states). This allows the use Such a property relates three events: the critical situation of very efficient methods based on reachability 1151, occurrence, the alarm, and the deadline. The latter can be 1201. provided externally as well as it can easily be expressed in A safety property can be checked on an abstraction LUSTRE.A general pattern for this property is the following of the actual program. Informally, if a safety property one: holds for a program, it also holds for programs whose “Any occurrence of event A is followed by an set of behaviors is a subset of the initial one. Thus it is occurrence of event B before the next occurrence possible to abstract programs by ignoring details, for of event C.” instance numerical computations; their set of behaviors However, this formulation is not directly translatable into will become larger and properties that hold on these LUSTRE,as it refers to what happens in the future following abstractions will also hold on the actual programs. an A occurrence, while LUSTREonly allows references to Safety properties can be checked modularly. Properties the past with respect to the current instant. That is why we of submodules can be combined so as to derive a first translate it into the equivalent past expression: property of the whole module. This allows proof “Any time C occurs, either A has never occurred complexities to be reduced, thanks to modular decom- previously, or B has occurred since the last position according to a program structure. In view of occurrence of A.” this discussion, we will propose methods for specifying Let us define a node, taking three boolean input parameters and checking simple safety properties about LUSTRE programs. A, B , C, and returning a boolean output X such that such that X is always true if and only if the property holds:

A. Specification of Safety Properties node onceBfromAtoC(A,B,C: bool) Many formalisms have been proposed in order to ex- returns (X: bool); press properties of real time parallel programs. Two main let approaches can be distinguished: those based on temporal X = implies(C, never(A) or logics 1281, [31] and those based on automata theory (Petri since(B,A)); nets, STATECHARTS,timed graphs [I] and process calculi tel [27]). Such formalisms should clearly allow any interesting property to be expressed, but should also provide an easy The equation defining x uses three auxiliary nodes: and readable expression for it; proving a certain property . The nodes implies implements the ordinary logical is of poor interest if one cannot be convinced that it is implication: actually the desired property of the system. This led us to investigate if it were possible to take advantage of LUSTRE’S node implies(A, B: bool) returns declarative aspect, so as to use it for expressing properties (AimpliesB: bool); of LUSTRE programs 1231. A positive answer is based on let AimpliesB = not A or B; tel. the following considerations: . The node never returns the value true as long as its

1314 PROCEEDINGS OF THE IEEE, VOL. 79, NO. 9, SEPTEMBER 1991 ______------I input has never been equal to true. Then it returns false In! for ever: p_, Q q-tI node never(B: bool) returns B’ I -I (neverB: bool); P’ let neverB = (not B) -> (not B and Fig. 5. Verification program. pre(neverB)); tel. of equations defining B, and whose only output is B (cf. Fig. 5). Since the compiler is then requested to only compute Finally, the node since has two inputs and it returns B, it will only take into account the part of the program true if and only if, either its second input has still not which concerns that computation, and this can be expected been true, or its first input has been true at least once to a smaller graph. Given that graph, verifying the since the last true value of the second input: property corresponds to check that in none of the states, the code performs an assignment of the output to false. node since(X,Y: bool) returns A third issue in reducing the size of the graph consists (XsinceY: bool); of using assertions for expressing assumptions when the let property to be checked is suspected to hold only on XsinceY = if Y then X else these assumptions. Assertions are also useful for expressing (true -> X or pre(XsinceY)); properties of numbers which otherwise would be ignored tel. by the compiler. For instance, if a program uses numerical tests such as X<=Z and Y<=Z, the assertion:

A realistic example has been studied in [17]: Most critical assert not(X<=Y and Y<=Z and not properties of a nuclear plant monitoring program have been x<=z ) ; expressed in LUSTRE, thanks to a small set of general purpose temporal operators similar to onceBf romAtoC, prevents the compiler from generating states satisfying never or since. z if ON then true the expression of properties in the same language as the else if OFF then false program may help in solving this problem. else pre(STATE); In the LUSTREcase, a state graph already exists corre- tel. sponding to the control automaton built by the compiler. This graph is an abstraction of the actual state graph since However, this version has a flaw: in the call it expresses only the control and ignores many details concerning non boolean variables, and boolean ones which state = SWITCH-l(button, button, init) do not influence that control. As noticed above, if properties to be checked depend essentially on booleans taken into the output does not change each time the button is pushed, account in the control graph, and if these properties are as we might expect. Thus a more general version should safety ones, such an abstraction is a sensible one for take into account the previous STATE when checking the checking purposes and yields in general much smaller inputs ON and OFF: graphs. An important observation for decreasing the total graph size consists of taking into account the property to node SWITCH(ON, OFF, INIT: bool be checked when building the state graph. In the case of returns (STATE: bool); LUSTREthis is easily achieved since the same language let applies to properties and programs: in order to prove that an expression B is an invariant of the program P, we build 4Such a node could have been used in defining the variable is-set in a new program P’ made of the body of P and of the system the CG1 (cf. Section 11-D) version of watchdogs.

1315 HALBWACHS et a1 SYNCHRONOUS DATAFLOW PROGRAMMING LANGUAGE LUSTRE

~___~- - ~ - ~~ (a) Fig. 7. Modular verification.

never assigned false. It has been used to check the above Fig. 6. Assumption-dependent equivalence of programs. mentioned nuclear plant control system [ 171. Though this program used computations on real numbers, the state STATE = INIT -> if ON and not graphs it needed to build appeared to be quite small (up pre(STATE)then true to 1000 states). else if OFF and Of course, the validity of the proof relies on the satisfac- pre(STATE) then false tion of the synchrony hypothesis: All the proof is performed else pre(STATE); “inside” the synchronous model, and has nothing to do with tel. performance analysis. As mentioned before, checking the validity of the synchrony hypothesis amounts to evaluate We could wish to verify that this generalization is correct, the maximum reaction time of the program on a given in the sense that both versions behave in the same way as machine. soon as the inputs ON and OFF are never true at the same time. This is achieved by constructing a comparison node V. CURRENTACTIVITIES which calls both nodes with same inputs and compares their outputs, under the assumption that ON and OFF inputs are A. The Next Compiler Version exclusive (cf. Fig. 6): In Section 111, the LUSTRE-V2 compiler currently available was described. However, from experiments conducted with node COMPARE(ON, OFF, INIT: bool) this version, some serious drawbacks have been identified, returns (OK: bool); and an improved version is currently being designed. We var state, state-1 : bool; briefly discuss here the main trends adopted in this new let design. state = SWITCH(ON, OFF, INIT); Automata minimization: As indicated above, automata State-1 = SWITCH_l(ON, OFF, INIT); provided by the current compiler are far from being min- OK = (state = state-1); imal, while this is not the case with ESTERELgenerated assert not(0N and OFF); automata. The suspected reason for this may be the fol- tel. lowing one: ESTERELis an imperative language offering powerful control structures (sequencing, interruptions, etc.). Compiling this node yields a five states automaton, each Furthermore, it is a medium to large grain parallel language transition of which assigns the value true to the output OK. in the sense that its parallel construct is an explicit one, and The last way to tackle the state explosion problem is its use may be tightly controlled by a pr~grammer.~This modular verification. Having to prove that an expression B allows “good programming” rules to be stated which lead is always true during the execution of a program P, calling to minimal automata. On the contrary, control in LUSTREis a node Q (cf. Fig. 7(a)), the idea is to decompose the proof hidden as it results from data dependencies, and LUSTREis a into a sub-proof concerning Q, and a sub-proof concerning fine grain parallel language in the sense that any expression P without Q: is a potentially parallel construct. Thus minor changes in a Find (by intuition) a property of Q, i.e., an expression program text may induce large variations in the automaton Con the input/output parameters of Q, and prove that size, and though some causes of state explosion have been C is always true during any execution of Q. identified, these cannot be easily synthesized as sensible Now, consider Q as being part of the environment of programming rules. The problem of efficiently compiling P, i.e., replace in P the call to Q by the assertion LUSTREis therefore intrinsically difficult. Several solutions assert C. Then try to prove the invariance of B on are currently investigated: the modified program (cf. Fig. 7(b)). A posteriori minimization: The use of an automaton An example making use of this modular decomposition minimizer such that ALDEBARAN(cf. Section 111-E) may be found in [18]. which has already been interfaced so as to process A prototype verification tool called LESAR(by analogy OC automata, is a low cost solution. But it applies with the CESARfamily of model checkers) has been im- ‘Though the main ESTERELassumption is that the synchronous product plemented: given a program with a single boolean output, of automata limits state explosion with respect to an asynchronous product, it goes through the states and checks that the output is it still may be the main cause of state growth.

1316 PROCEEDINGS OF THE IEEE, VOL. 79, NO. 9, SEPTEMBER 1991 only after a successful automaton generation, and this execution schemes. There can be at least two reasons for cannot be the case when a state explosion occurs. that discrepancy: On the fly minimization: It is based on an analysis Parallelism in LUSTREis intended toward expressive- of state explosion. The main reason seems to be ness and adequacy with the culture of control systems that LUSTREvariables are defined during the whole engineers, and this is independent of any execution program execution, without taking much care of their scheme. effective use. Although this is a nice feature of the In contrast with the above mentioned languages, paral- language from a programmer’s point of view, it leads lelism in LUSTREis a fine grain one, and its concurrent the compiler to distinguish states which differ only on execution would be rather inefficient. On the contrary, values that have no influence on the present and future we have seen that very efficient sequential codes sequence of outputs. This suggests a “demand driven” (with respect to execution time) can be generated, and state generation strategy, where states are created if furthermore, sequential execution allows the transition and only if their influence on the input output behavior time to be accurately bounded. of the program is asserted [7]. This strategy has been However, many control and monitoring systems which successfully implemented. constitute the main application domain of LUSTRE, are Source code optimization: As mentioned above, some distributed systems for several reasons: performances, fault rules are known which could reduce the automaton tolerance, location of sensors and actuators, etc., and these size, but cannot be sensibly edicted as programming systems are most often programmed separately. This may rules. The idea is then to take advantage of the large not be a bad solution, as it may correspond to a modular versatility of LUSTREprograms which is due to its decomposition of systems, but it frequently raises difficult mathematical aspect (for instance the definition princi- debugging problems, and an overall validation of such ple) so as to use these rules as optimizing rules. There systems is usually impossible. An alternative method can are experiments being carried on in this direction as be based on an automated tool producing distributed code well. from LUSTREprograms and user-provided distribution com- Transition code size: Besides the automaton size, it mands (for instance, “compute variable X on location Ll”). happens that the codes of transitions become exceedingly This would allow a whole application to be programmed large. This results from an inadequacy of the scheduling in LUSTRE,without taking care of distribution problems, algorithm which produces that sequential code. One of its and then, this application could be easily debugged and tasks consists of transforming conditional expressions into validated using standard LUSTREmethods. Provided the au- conditional statements and the order according to which tomatically produced distributed program preserves LUSTRE tests are opened and closed appears to be critical with semantics, it can be expected that any debugging and respect to code size (cf. Section 111-C). Heuristics are being validation performed on the centralized program will also investigated so as to solve this problem. hold for the distributed one. Such a tool, called OC2REP, is Modular compiler: It may also happen that a minimal described in [4], and has been implemented. Given an OC automaton of a program still remains very large. This hap- program and a set of distribution commands, it automat- pens when the program is made of many quasi-independent ically produces several OC programs which communicate parts, and then its number of states become as large as through FIFO queues thanks to statements such that: the product of state numbers of the parts. A good solution in this case would consist of generating an automaton for put-type(i:location; exp:type); each part and then of linking together these automata. This raises two problems. First, it has been noted (Section 111-B) whose execution at location j consists of inserting the value that modularly compiling pieces of LUSTREprograms is in of exp in the queue j of location i, and: general impossible. However [33] proposed a method for identifying in a program those pieces that can be compiled get-type(j:location; var x:type); separately. Second, this may result in a significant decrease of the code length, but at the expense of execution time. whose execution at location i consists of waiting if queue j Although the method has not yet been implemented, it is empty, and else, of assigning the head of the queue to x. is foreseen that it should keep under the programmer’s Note that the queue mechanism and the fact that puts control, so as to reach a satisfactory balance between code and gets are inserted in convenient order allow messages length and execution time. not to identify the transmitted values, but only the sending and destination locations. The distributed programs are well synchronized, deadlock free, and meet the functional B. Distributed Programming semantics of LUSTRE^. Experiments also show that this Up until now, the only execution scheme considered for method avoids difficult distributed debugging problems. LUSTREprograms is a purely sequential one. This does not However, accurate bounds on the transition times are diffi- seem very consistent with the highly parallel aspect of the cult to get, and their evaluation constitutes a real problem. language and with the fact that most parallel languages such that OCCAMand ADA have parallel and concurrent 6This also applies to Esterel since the input of the tool is an OC program.

HALBWACHS et al.: SYNCHRONOUS DATAFLOW PROGRAMMING LANGUAGE USTRE 1317 C. Hardware Issues the program be deterministic and deadlock-free. The free The adequacy of LUSTREfor the description of digital use of hiatons (i.e., “absent” data symbols) in the semantics circuits has been shown in several papers [19], [22], [38]. makes SIGNALa more powerful language than LUSTREin Moreover, it can be expected that circuit proof and valida- the sense that the internal clock of program can be faster tion may benefit from LUSTREproof techniques. Another than the inputs faster clock. In our opinion, the drawback of interesting issue is hardware design from boolean LUSTRE the approach lies in the fact that the clock calculus is much specifications and descriptions. Some work on this topic is more complex, and can hardly be mentally performed by currently undertaken in cooperation with Digital Equipment a programmer. “Paris Research Laboratory” [35]. The idea is to implement 3) Imperative Synchronous Languages: Most synchronous on hardware the network of operators corresponding to the models and languages are imperative ones-e.g., SCCS program, and successful achievements have been obtained [27], ESTEREL,SML, STATECHARTS-and therefore their in this direction, using “programmable active memory” programming style is very different. Comparison ex- circuits [12]. periments undertaken with ESTERELshowed that some problems could fit better with the imperative style, while others did not. This seems to indicate that a good reactive VI. CONCLUSION programming tool box should offer the possibility of In this paper, the LUSTRElanguage, its main applications, mixing both approaches. As both languages share many and its associated tools have been presented. As concluding tools in common, this may become a practical objective remarks, we will compare the LUSTREapproach with some in the future. It should also be noted that the data-flow alternative approaches, from both programming language aspect of LUSTREmakes it less dependent on synchronous and verification points of view. execution schemes than imperative languages. For instance a denotational semantics of LUSTREis given in [5], which A. Related Programming Languages does not impose a synchronous execution. This may open 1) Data Flow: The data flow model has been a basis of the door to many asynchronous execution schemes together several programming languages, for instance [3], [9], [ll], with their semantic interpretation. [26] and it has been given a nice formal definition by Kahn in [25]. When trying to locate LUSTREwithin the data flow B. Proof Techniques world, it looks very close to LUCIDfrom a syntactical point The use of LUSTREas a language for expressing program of view. This similarity is not casual since LUCIDwas the properties allows it to be compared with so-called “real- first main reference in the design of LUSTRE.However, the time” logics [2], [24], [28], [37]. These logics are mainly final language is quite different from its model. This is obtained by adding a quantitative time dimension to ordi- due to the choice of the Kahn model as the basic one for nary temporal logics where time is only seen as an ordering LUSTRE:in this model, newly computed values can only of events. Our proposal differs in that we remain within the be appended at the end of a sequence of already computed framework of temporal logics, and consider time as a given values, while LUCIDmodel allows them to be appended external event. This presents two advantages: first, the logic anywhere in the sequence. This raises a lot of problems does not grow in complexity, and it allows a multiform con- when efficient execution mechanisms are required, and it cept of time to be handled. On the same topic, we have also poorly meets the point of view of reactive systems. Thus stressed in the paper the interest of using the same language LUSTREcan be first seen as some restriction of LUCIDto the for both writing programs, and expressing properties to be Kahn model. But the latter soon appeared still too general satisfied by these programs. Concerning proof techniques, when bounded memory and bounded reaction time were we first began by considering inductive methods, based required. Clearly, recursive node call had to be forbidden, on an axiomatic approach. Though some work has been but also the use of sampling and blocking operators had to done in that direction [14], it soon appeared that methods be strictly restricted for that purpose. This originated the based on state enumeration (“model checking”) could be concept of LUSTREclocks which is the final distinguishing more efficient. Several improvements of the method in the feature of the language. particular case of LUSTREare described in the paper. 2) Signal: Another language quite similar to LUSTREis SIGNAL(see this issue), and comparing both is not an easy task. A main issue here is their distinct semantic model; ACKNOWLEDGMENT in our opinion SIGNALdoes not belong to the Kahn family Many people have been involved in the project: J.-L. of languages, which is based on functions over sequences, Bergerand and E. Pilaud played a great part in the language and on functional composition, but on a concept of “pro- definition, J. Plaice defined and implemented the LUSTRE-V2 gramming by constraints”: each SIGNALconstruct denotes compiler, Anne-CCcile Glory and F. Ouabdesselam were a finite-memory relation between “hiatonised” sequences, involved in the work on program specification and proof and a program is the intersection of such relations. A within the framework of a contract with Merlin-Gerin program has a bounded memory but it can be relational company. The LUSTREproject received constant attention (i.e., non deterministic), and the object of SIGNALclock and help from G. Berry and the ESTERELteam. In particular, calculus consists of finding an execution scheme such that the authors are indebted to them for the compiling technique

1318 PROCEEDINGS OF THE IEEE, VOL. 79, NO. 9, SEPTEMBER 1991 of LUSTRE.They are also indebted to A. Benveniste for [23] N. Halbwachs, D. Pilaud, F. Ouabdesselam, and A. C. Glory, its energy spent in promoting synchronous programming. “Specifying, programming and verifying real-time systems, using a synchronous declarative language,” in Workshop on Finally, they thank Costas Courcoubetis and the referees automatic verification methods for finite state systems, LNCS for their careful rereading of the manuscript. 407. New York: Springer Verlag. June 1989. [24] F. Jahanian and A. K. Mok, “Safety analysis of timing prop- erties in real-time systems,” IEEE Trans. Sofmare Eng., vol. SE-2, 1986. REFERENCES [25] G. Kahn, “The semantics of a simple language for parallel pro- gramming,” in IFIP 74 Amsterdam, The Netherlands: North [I] R. Alur, C. Courcoubetis, and D. Dill, “Model checking of Holland, 1974. real-time systems,” in Fifth IEEE Symp.Ton Logic in Computer [26] J. R. Mc Graw, “The VAL language: Description and analy- Science, 1990. sis,”TOPLAS, vol. 4, no. 1, Jan. 1982. [2] R. Alur and T. A. Henzinger, “A really temporal logic,” in 30th [27] R. Milner, “Calculi for synchrony and asynchrony,” TCS, vol. IEEE Symp. on Foundations of Computer Science, 1989. 25, no. 3, July 1983. [3] E. A. Ashcroft and W. W. Wadge, LUCID, the data-flow [28] B. Moszkowski and Z. Manna “Reasoning in interval temporal programming language. New York: Academic, 1985. logic,” in Workshop on Logics of Programs, LNCS 164. New [4] B. Buggiani, P. Caspi, and D. Pilaud, Programming distributed York: Springer Verlag, 1984. automatic control systems: A language and compiler solution, [29] D. Pilaud and N. Halbwachs, “From a synchronous declarative Tech. Rep. SPECTRE L4, IMAG, Grenoble, France, July 1988. language to a temporal logic dealing with multiform time,” in [5] J.-L. Bergerand, “LUSTRE: un langage declaratif pour le temps Symp. on Formal Techniques in Real-Time and Fault-Tolerant riel,” master’s thesis, Inst. National Polytechnique de Grenoble, Systems, LNCS 332, M. Joseph, Ed. New York: Springer France, 1986. Verlag, Sept. 1988. [6] G. Berry ”Real time programming: special purpose or general [30] J. A. Plaice, “Skmantiqueet compilation de LUSTRE, un langage purpose languages,” in IFIP Congress, 1989. declaratif synchrone,” Master’s thesis, Inst. National Polytech- [7] A. Bouajjani, J. C. Fernandez, and N. Halbwachs, “Minimal nique de Grenoble, France, 1988. model generation,” in Workshop on Computer-Aided Verifica- [31] A. Pnueli, “The temporal logic of programs,” in 18th Symp. on tion, June 1990. the Foundations of Computer Science, IEEE, 1977. [8] A. Bouajjani, J. C. Fernandez, and N. Halbwachs, “On the [32] J. A. Plaice and J-B. Saint, “The LUSTRE-ESTEREL portable verification of safety properties,” Tech. Rep. SPECTRE LIZ, format,” 1987, INRIA, Sophia Antipolis, France, unpublished IMAG, Grenoble, France, Mar. 1990. report. [9] S. A. Babiker, R. A. Fleming, and R. E. Milne, “A tutorial for [33] P. Raymond, “Compilation stparie de programmes LUSTRE,” LTS,” RR 225. 84. 1, Standard Telecommunication Labs., 1984. Tech. Rep. SPECTRE L5, IMAG, Grenoble, France, June 1988. 101 D. Borrione and C. Le Faou, “Overview of the CASCADE 1341 V. Roy and R. de Simone, “An AUTOGRAPH Primer,” Tech. multilevel hardware description language and its mixed mode Rep. INRIA, May 1989. simulation mechanisms,” in Computer hardware description [35] F. Rocheteau, “Programmation d’un circuit massivement par- languagcs arid their applications. Amsterdam, The Nether- allele a l’aide d’un langage dtclaratif synchrone,” Tech. Rep. lands: North Holland, Elsevier Science, 1985. SPECTRE L10, IMAG, Grenoble, France, June 1989. 111 M. Broy, “Functional specification of time sensitive communi- [36] J. L. Richier, C. Rodriguez, J. Sifakis, and J. Voiron, “Verifica- cating systems,” in REX Workshop, 1989. tion in XESAR of the sliding window protocol,” in IFIP WG-6.1 121 P. Bertin, D. Roncin, and J. Vuillemin, “Introduction to pro- 7th. Int. Conf on Protocol Specification, Testing and Verification grammable active memories,” Tech. Rep., Digital Paris Res. Amsterdam, The Netherlands: North Holland, 1987. Lab., June 1989. [37] R. L. Schwartz, P. M. Melliar-Smith, and F. H. Vogt, “An [13] E. M. Clarke, E. A. Emerson, and A. P. Sistla, “Automatic interval logic for higher-level temporal reasonning: Language verification of finite-state concurrent systems using temporal definition arrd examples,” Res. Rep. CSL-138, Computer Sci- logic specifications,”TOPLAS, vol. 8, no. 2, 1986;‘ ence Lab., SRI International, Feb. 1983. [14] P. Caspi, D. Pilaud, N. Halbwachs, and J. Plaice, LUSTRE: A [38] G. Thuau and D. Pilaud, ‘‘Using the declarative language declarative language for programming synchronous systems,” LUSTRE for circuit verification,” in Workshop on Designing in 14th ACM Symp. on Principles of Programming Languages, Correct Circuits. Oxford, U.K., Sept. 1990. Jan. 1987. [39] D. Vergamini, “Verification by means of observational equiva- [15] C. Courcoubetis, M. Vardi, P. Wolper, and M. Yanakakis, lence on automata,” Tech. Rep. 501, INRIA, 1986. “Memory efficient algorithms for the verification of temporal properties,” in Workshop on Computer-Aided Verification, June 1990. 161 J. C. Fernandez, “Aldebaran : un systkme de vtrification par rtduction de processus communicants,” Master’s thesis, Univ.6 Joseph Fourier, Grenoble, France, 1988. 171 A-C. Glory, “V4rification de propriitks de programmes pots de donntes synchrones,” Master’s Thesis, Univ.6 Joseph Fourier, Grenoble, Dec. 1989. 181 N. Halbwachs and F. Lagnier, “Anexperience in proving regular networks of processes by modular model checking,” Tech. Rep. SPECTRE L13, IMAG, Grenoble, France, Mar. 1990. [19] N. Halbwachs, A. Lonchampt, and D. Pilaud, “Describing and designing circuits by means of a synchronous declarative language,” in IFIP Working Conf “FromHDL Descriptions To Guaranteed Correct Circuit Designs”, Sept. 1986. [20] G. J. Holzmann, “On limits and possibilities of automated protocols analysis,” in IFIP WG-6.1 7th. Int. Conf on Proto- Nicholas Halbwachs received the Ph.D. degree col Specification, Testing and Verification. Amsterdam, The in 1984 on the modeling and analysis of real- Netherlands: North Holland, 1987. time system behavior after a first thesis on the [21] D. Hare1 and A. Pnueli, “On the development of reactive semantic analysis of programs. systems,” in Logic and Models of Concurrent Systems, NATO Together with Paul Caspi, he participated in Advanced Study Inst. on Logics and Models for Verification the design of the language LUSTREfrom its be- and Specification of Concurrent Systems, New York: Springer ginning. His domain of interests concerns paral- Verlag, 1985. lel and real-time system design and verification, [22] N. Halbwachs and D. Pilaud, “Use of a real-time declarative lan- both from formal (semantics, specification, and guage for systolic array design and simulation,” in International verification methods) and practical (, Workshop on Systolic Arrays, July 1986. verification tools) points of view.

HALBWACHS et al.: SYNCHRONOUS DATAFLOW PROGRAMMING LANGUAGE LUSTRE 1319

~~ -- Paul Caspi received the Docteur Cs Sciences Daniel Pilaud received the “Docteur de 3’ thesis from INPG, Grenoble, France. cycle” in computer science from the lnstitut Currently, he is ChargC de Recherche CNRS National Polytechnique de Grenoble in 1982. at the Laboratoire de Genie lnformatique of From 1982 until 1989 he was teacher cum IMAG in Grenoble, France. His previous re- researcher at the “Ecole Nationale SupCrieure search activities mainly dealt with the use of d’hformatique et de MathCmatiques AppliquCes computers in process control, and were espe- de Grenoble.” In 1989, he joined VERILOG. He cially concerned with dependability problems is currently manager of the VERILOG Rhone- in critical applications, from both hardware and Alpes Research and Development Center, where software points of view. This led him to partic- a CASE tool based on the language LUSTREis ipate in the design of the synchronous data flow being developed. His research interests include LUSTRE.He is now mainly concerned with the theory of synchronous data specification implemental tion and validation of real time systems. flow, and the problem of building distributed systems from synchronous programs. He also acted as a consultant for several companies and French admistrations, on problems of dependable computing systems design and validation.

Pascal Raymond is working towards the Ph.D. degree at the Ldboratoire de GCnie Informatique under a grant from the French Department of Research and Technology. He designed the new compiler LUSTRE-v3

1320 PROCEEDINGS OF THE IEEE, VOL 79, NO 9, SEPTEMBER 1991

-- ~~ __~-