Lustre, short for Lustre Synchronous Dataflow Programming Language, was created by Jean-Pierre Talpin and Claude Caspi in the 1980s. Lustre is a declarative synchronous dataflow language used for programming reactive and real-time embedded systems, particularly in safety-critical domains such as avionics, automotive, and industrial control systems. Developers can access Lustre by downloading implementations such as Lustre for Windows or Lustre for Linux and macOS, which provide compilers, libraries, and documentation for various platforms, enabling simulation, verification, and code generation for embedded targets.

Lustre exists to provide a programming model tailored for reactive systems that must respond deterministically to input events. Its design philosophy emphasizes predictability, formal verification, and ease of reasoning about time-dependent behaviors. By using synchronous dataflow semantics, Lustre solves the problem of designing reliable, predictable, and analyzable control software, making it suitable for avionics autopilots, automotive controllers, and industrial automation.

Lustre: Streams and Nodes

Lustre operates on infinite sequences of values called streams. Streams represent time-varying signals, and nodes define reusable computation units operating on these streams. Streams form the fundamental abstraction for reactive computation.

node Counter(reset: bool) returns (count: int);
var temp: int;
let
    temp = if reset then 0 else pre(count) + 1;
    count = temp;
tel

In this example, pre refers to the previous value of a stream, and the node produces a counter that resets when the input is true. This stream-based model allows precise modeling of time-dependent behavior, conceptually similar to SCADE and Simulink.

Lustre: Operators and Expressions

Lustre supports arithmetic, logical, relational, and temporal operators that operate on streams. Expressions define the computation of output streams from input streams.

node SignalProcessing(x: real) returns (y: real);
let
    y = x + pre(x) * 0.5;
tel

This example computes a simple first-order filter using the previous value of the input stream. Operators applied to streams allow concise and declarative definitions of reactive behaviors, comparable to SCADE expressions and Simulink block computations.

Lustre: Node Composition and Modularity

Lustre supports modular design by composing nodes into hierarchical structures. Nodes can be reused and interconnected to build complex reactive systems.

node TopSystem(reset: bool; input: real) returns (output: real);
var counter_val: int;
let
    counter_val = Counter(reset);
    output = SignalProcessing(input);
tel

By connecting nodes, developers can build complex systems from simpler components. This modular composition approach is similar in philosophy to hierarchical modeling in Simulink and modular design in SCADE, supporting maintainable and verifiable code structures.

Lustre: Verification and Real-Time Execution

Lustre integrates well with formal verification tools and code generators for real-time embedded systems, ensuring deterministic behavior and safety compliance.

-- Example property in Lustre for verification
assert count >= 0;

Assertions enable static checking of system properties, ensuring safety and correctness. Verification integration is a key feature in safety-critical applications, conceptually similar to model checking in SCADE and formal verification in synchronous languages.

Lustre is used in avionics, automotive systems, and industrial controllers, where deterministic behavior and formal correctness are paramount. Its synchronous dataflow model, node-based modularity, and support for formal verification make it a robust choice for reactive and embedded systems. When combined with tools like SCADE and Simulink, Lustre enables developers to design, simulate, and verify safety-critical real-time software efficiently.