Keywords: static analysis, abstract interpretation, interprocedural analysis, procedure summaries, convex polyhedra, reactive systems, synchronous programming. 6.2.2 Scheduler . . . . . . . . Semantics 2.1.1 Transition Systems

How can one check a routine in the sense of making sure that it is right ?

Résumé

La présence de bugs ou de dysfonctionnements dans les systèmes critiques peut avoir des conséquences terribles. La validation et l'analyse des programmes embarqués dans les systèmes critiques est d'une importance majeure pour garantir que les logiciels présents soient conformes à leur spécification et dépourvus d'erreurs à l'exécution.

L'analyse statique par interprétation abstraite calcule une approximation sûre de l'ensemble des états accessibles d'un programme. Elle permet de découvrir des propriétés invariantes des programmes en les représentant par des éléments d'un domaine abstrait. Les domaines abstraits numériques, comme le domaine des octogones ou des polyèdres convexes, ont des niveaux de précision différents. Les outils industriels d'analyse statique n'utilisent généralement pas les domaines abstraits numériques les plus expressifs, comme le domaine des polyèdres convexes, à cause de la complexité de leurs opérations.

Nous présentons dans cette thèse une analyse modulaire des programmes pour la découverte de propriétés numériques, basée sur le calcul de résumés disjonctifs et relationnels de procédures. Les résumés de chaque procédure sont calculés de manière ascendante (bottom-up) et utilisés dans l'analyse de l'effet des appels de procédure. Bien que notre approche soit appliquée à l'analyse de relations linéaires, ou interprétation abstraite polyédrique, pour améliorer son passage à l'échelle, elle est définie dans un cadre plus large applicable à n'importe quel domaine abstrait relationnel.

Les résumés disjonctifs de procédures sont des ensembles finis de relations d'entréesortie représentées par des éléments d'un domaine abstrait relationnel. Ils sont calculés en utilisant un partitionnement de la précondition d'une procédure. Nous proposons des heuristiques pour calculer des partitions de préconditions. Nous présentons aussi des améliorations concernant la précision du calcul des résumés, notamment grâce à un traitement particulier des préconditions. Notre approche s'applique également aux procédures récursives, où les résumés sont calculés en fonction d'eux-mêmes.

Notre analyse modulaire à été implémentée dans un nouvel outil d'analyse statique pour les programmes C, appelé mars. Nos expérimentations montrent que notre approche peut réduire significativement le temps d'analyse pour l'analyse des relations linéaires, par comparaison avec une analyse classique qui analyse les procédures dans chaque contexte d'appel. La précision des résultats n'est pas considérablement diminuée et peut même être améliorée grâce à l'usage de la disjonction dans les résumés.

Dans une seconde partie, nous présentons une approche pour l'analyse modulaire des systèmes réactifs. Nous proposons une représentation flexible des composants réactifs appelée Automates Relationnels de Mode, ou Relational Mode Automata (RMA), permettant une analyse des systèmes réactifs à différents niveaux d'abstraction. Les automates relationnels de mode peuvent être construits automatiquement à partir des résumés disjonctifs des procédures implémentant la réaction de chaque composant. Les résultats de l'analyse de chaque composant peuvent être réutilisés dans l'analyse de systèmes réactifs de plus grande taille où chaque composant peut être instancié plusieurs fois. Cette approche est appliquée à l'analyse d'un système simplifié de contrôle d'un réseau de métro.

Mots clés : analyse statique, interprétation abstraite, analyse interprocédurale, résumés de procédures, polyèdres convexes, systèmes réactifs, programmation synchrone.

Chapter 1 Introduction

Many things have changed since the first paper on program verification by Alan Turing in 1949. Abstract interpretation and interprocedural analysis were born more than four decades ago. This thesis stands on the shoulders of giants.

Context

Today, embedded systems are everywhere. They are computer systems which are part of a larger device. The examples are numerous, from consumer electronics with smartphones or digital watches, and to very large and complex systems in avionics, transportation or nuclear power plants. Many of them are produced in large volumes and most of them are difficult to update, such as the firmware deeply embedded in communication subsystems of smartphones or the control software of nuclear reactors.

Many embedded systems have real-time constraints and some of them are deemed safety-critical in which any bug of the controlling software or malfunction of the device can have catastrophic consequences, with a major impact on the environment and may cause a large number of injuries or death. The examples of incidents involving a software bug are well-known. The Ariane 5 crash [START_REF] Lions | Ariane 5 flight 501 failure report by the inquiry board[END_REF] in 1996 was due to an integer overflow. The Therac-25 radiation therapy machine [START_REF] Leveson | An investigation of the therac-25 accidents[END_REF] gave patients massive overdoses of radiation in at least six accidents between 1985 and 1987 due to various software defects and wider software engineering problems. More recently, the Boeing Dreamliner 787 [START_REF] Administration | Airworthiness directives; the Boeing company airplanes[END_REF] had to be rebooted every 248 days due to a counter overflow in the firmware of the AC power management system. This motivates the need for a reliable and systematic validation process of safetycritical systems providing trustworthy guarantees that the software satisfies its specification and that it is devoided of runtime errors. There are several families of approaches:

• Testing or dynamic analysis consists in observing the behavior of the software at runtime on some well-chosen inputs. Although this approach can detect bugs, it is not exhaustive, since all inputs and scenarios can not be tested in general. Testing can not prove the absence of bugs. • Static analysis is a class of techniques performed on a static representation of a program without executing it. Some of these techniques mathematically prove that a program does not have bugs whereas others are able to find bugs. Program analysis by abstract interpretation computes a sound approximation of the Introduction set of reachable states of a program. It discovers invariant properties of programs which are represented by elements of an abstract domain. These invariants can be used to prove the absence of errors at runtime, such as arithmetic overflows, or to prove a given assertion. Industrial tools such as Polyspace [START_REF]Polyspace code prover, mathworks[END_REF] or Astrée [START_REF] Blanchet | A static analyzer for large safety-critical software[END_REF] can prove the absence of runtime errors in large embedded software written in C. Some tools such as PIPS [START_REF] Irigoin | Semantical interprocedural parallelization: An overview of the PIPS project[END_REF] Clousot [START_REF] Fähndrich | Static contract checking with abstract interpretation[END_REF] or Infer [START_REF] Calcagno | Infer: An automatic program verifier for memory safety of c programs[END_REF] are applied to a more general variety of software.

Contributions

Astrée made the achievement to scale to large embedded programs written in C, at the expense of avoiding more precise abstract domains like convex polyhedra due to their computational complexity. Less expressive abstract domains such as intervals of integers or octagons are used instead. Despite large programs being organized as collections of functions or procedures, Astrée performs a top-down analysis of programs without really considering their interprocedural structure. Procedures are either inlined or reanalyzed each time they are called.

Modular Analysis with Relational Procedure Summaries

In this thesis, we are interested in improving the scalability of Linear Relation Analysis, or abstract interpretation based on convex polyhedra, by computing precise relational summaries of procedures. We make use of the procedural structure of programs to propose a new modular analysis for the automatic discovery of numerical properties. Although specifically applied to convex polyhedra, it is based on a more general framework usable with any relational abstract domain.

Our analysis framework comes with a formalization of relational abstract interpretation that we did not find elsewhere. Based on relational collecting semantics, we present the construction of relational procedure summaries as abstract input-relations between the initial values of procedure parameters and their final value at the exit of a procedure.

Procedures can exhibit very different behaviors which can not be expressed precisely by a single element of a classical abstract domain such as convex polyhedra. In order to have precise procedure summaries, we compute disjunctive relational summaries, where each disjunct is an abstract input-output relation represented by a separate element of a relational abstract domain.

Taken together, the sources of each individual relation in a disjunctive summary form an abstract partition of the procedure precondition to account for all the possible values of parameters. The precision of a disjunctive summary is determined by the quality of the precondition partitioning. We give heuristics to compute an abstract partition of a procedure precondition. We also give ways to improve the precision of summary computation. As we show that preconditions are at the heart of precise summaries, they are entitled to a specific and careful treatment during summary computation. Summaries are computed once and for all in a bottom-up fashion and used to analyze the effect of procedure calls.

We also show that our approach applies to recursive procedures. In some way, the summary of a recursive procedure must be computed in terms of itself.

Outline

We implemented this approach in a new static analyzer called mars (Mars Abstract Interpretation Research System) based on Clang which consists of 20000 lines of C++ and 4000 lines of OCaml. It was designed from the ground-up for the experimentation of new static analyses. The mars intermediate representation has been designed specifically to ease the development of static analyses by abstract interpretation and to provide highquality source traceability information. This work has been published in [START_REF] Boutonnet | Disjunctive relational abstract interpretation for interprocedural program analysis[END_REF].

Modular Analysis of Reactive Programs

Many embedded programs must react continuously to inputs at a speed determined by their environment. They are called reactive programs. Reactive programs can be written in languages like C or in special-purpose languages like synchronous languages such as Lustre, Esterel or Signal. The flight control software of the Airbus A380 was written in SCADE which is an industrial dataflow synchronous language based on Lustre.

Reactive programs are usually organized as collections of components computing the system reaction to inputs and producing outputs. Reactive components can also have memory which is updated at each reaction step. They are implemented by step procedures which are called repeatedly inside a global infinite loop.

Although Astrée scales to large C programs generated from SCADE, it does not take advantage of the specific nature of reactive programs and the structuring into components is completely lost during the analysis.

In a second part, we pave the way toward a new modular analysis of reactive systems, based on the computation of disjunctive relational summaries of step procedures. We propose an abstraction of reactive programs designed specifically for analysis called Relational Mode Automata (RMA). It provides a flexible representation allowing the expression of reactive systems behavior at various levels of detail. RMA are constructed automatically from the disjunctive relational summary of a step procedure. We propose a reachability analysis of RMA and their parallel composition which does not require a costly explicit construction of the parallel product prior to the analysis.

Various heuristics are given to reduce the level of precision of a given relational mode automaton, in order to achieve different tradeoffs with respect to precision and analysis performance. The analysis results of a component can be used for the modular analysis of a larger system containing it, by computing its abstract effect in other step procedures.

This approach is currently implemented on small examples using the Python library PyApron which provides a high-level binding to the Apron abstract domain library.

Chapter 1

Introduction

Part I gives an introduction to static analysis by abstract interpretation and gives an overview of the state of the art regarding the interprocedural analysis of programs. It first presents the program representation used throughout this thesis and recalls some basic notions of semantics, along with the standard framework of abstract interpretation. It also mentions some improvements to classical abstract interpretation for precision. Then, it gives an overview of interprocedural analysis and its main approaches, from foundational works to the state of the art, giving a modest glimpse to its abounding literature ranging over more than four decades.

Part II presents our modular analysis based on the computation of disjunctive relational procedure summaries. It first describes our general framework with a formalization of relational abstract interpretation. We give a particular application of this framework to the convex polyhedra abstract domain. A special light is shed on the treatment of preconditions and their role in summary computation. Then, we shows how disjunctive procedure summaries can be obtained based on precondition partitioning. We give several partitioning heuristics and improvements to summary computation. Finally, we present the implementation of the mars static analyzer, as well as some experimental results.

Part III is dedicated to our approach for a modular analysis of reactive systems. It starts with an introduction to reactive programs and synchronous languages, along with the main approaches for analysis and verification. Then, we propose a representation of reactive programs called Relational Mode Automata which are constructed automatically from the summary of a step procedure. We present the analysis of RMA and ways to tune their precision. Finally, we illustrate this approach on the example of a simplified subway control system.

Part I

State of the Art

The behavior of a program can be described by a transition system T = (S, I, τ ) where S is a set of states, I ⊆ S is a set of initial states and τ ⊆ S × S is a transition relation over the set S of states. We denote as s 1 → s 2 that there exists a transition (s 1 , s 2 ) ∈ τ from a state s 1 ∈ S to a state s 2 ∈ S. If U ⊆ S, we denote as τ (U ) = {s ∈ S | ∃s ∈ U, (s, s ) ∈ τ } the set of successors of U .

A state s ∈ S is said to be reachable if it can be produced from an initial state in a finite number of computation steps. Thus the set reach of reachable states is defined A state s ∈ S is reachable if it is connected to an initial state by the transitive closure τ of the transition relation τ .

Stated differently, a state is reachable if it is either an initial state or the successor of a reachable state by the transition relation τ . We can also define reach as the least solution of the fixpoint equation:

reach = I ∪ τ (reach)
In Section 2.2, we recall some basic notions of fixpoint theory which ensures that such a recursive definition makes sense.

Programs as Control Flow Graphs

We adopt the classical representation of programs by Control Flow Graphs (CFG), in contrast with other works using Abstract Syntax Trees, such as Astrée [START_REF] Blanchet | A static analyzer for large safety-critical software[END_REF] or Mopsa [START_REF] Miné | Design of a modular platform for static analysis[END_REF], or directly expressing program semantics as Horn clauses such as SeaHorn [START_REF] Gurfinkel | The SeaHorn verification framework[END_REF]. For simplicity, each node has a single output possibly leading to several successor nodes. This means that classical test nodes are transformed into pairs of conditions appearing at the beginning of statement nodes, where the associated transfer functions intersect their argument with the condition of the test (the then part) or its negation (the else part). Since conditions guard statement nodes, the transfer functions f ν are partial, returning ⊥ when their argument does not satisfy the condition.

From CFGs to transition systems

The semantics of a CFG can be expressed as a transition system (S, I, τ ) where the set of states is S = N × D and each state is a pair (ν, d) made of a node and a variable valuation. The set of initial states is I = N 0 × D where N 0 is the set of start nodes of the CFG. The transition relation τ is defined as: It is represented by the control flow graph on its right.

((ν, d), (ν , d )) ∈ τ ⇔ (ν, ν ) ∈ E ∧ d = f ν (d) = ⊥ if ν is a statement node d if

Collecting Semantics

Classically, program states are partitioned according to the nodes of the CFG. It is a particular instance of what is called trace partitioning [START_REF] Rival | The trace partitioning abstract domain[END_REF], see Section 2.5.2. Instead of computing the reachable states of the transition system, we compute the set X ν of reachable variable valuations at each CFG node ν, defined as:

X ν = {d | (ν, d) ∈ reach}
The sets X ν satisfy the following system of equations called the collecting semantics of the program:

X ν =        D if ν is a start node f ν (X ν ) if ν is a statement node and (ν , ν) ∈ E (ν ,ν)∈E X ν if ν is a junction node
We can also write this system of equations as a vectorial fixpoint equation X = F (X) where X ∈ D k .

Example 2.1.1. We give the collecting semantics of the simple program of Figure 2.1. There is a unique variable i of integer type, the set of valuations is D = Z. The semantic equations are:

X 0 = Z X 1 = X 0 [i := 0] X 2 = X 1 ∪ X 4 X 3 = (X 2 ∩ (i < 100))[i := i + 1] X 4 = X 3 X 5 = X 2 ∩ (i ≥ 100) X 6 = X 5
Chapter 2

Program Analysis by Abstract Interpretation

From this system of equations, we define a semantic function F : D k → D k as follows:

F           X 0 X 1 X 2 X 3 X 4 X 5 X 6           =           Z f ν 1 (X 0 ) X 1 ∪ X 4 f ν 3 (X 2 ) X 3 f ν 5 (X 2 ) X 5           =           Z X 0 [i := 0] X 1 ∪ X 4 (X 2 ∩ (i < 100))[i := i + 1] X 3 X 2 ∩ (i ≥ 100) X 5          
The functions f ν 1 : D → D, f ν 3 : D → D and f ν 5 : D → D are the transfer functions representing the effect of statement nodes ν 1 , ν 3 , ν 5 . The system of semantic equations is equivalent to the vectorial fixpoint equation X = F (X) with X ∈ D k .

Fixpoint Theorems

As most interesting objects in computer science, program semantics are defined by systems of fixpoint equations. The existence of solutions to such equations results from fixpoint theory and order theory. We introduce in this section some basic definitions and notations regarding partially ordered sets and lattices. m for every upper bound m of S. An element l ∈ D is a lower bound of S ⊆ D if ∀x ∈ S, l x. An element L ∈ D is the greatest lower bound of S, denoted as S, if l L for every lower bound l of S. Definition 2.2.2 (Lattice). A lattice (L, , , ) is a partially ordered set in which every pair {a, b} ∈ L of elements of L has a least upper bound a b = {a, b} and a greatest lower bound a b = {a, b} in L. The least upper bound : L × L → L is called the join operator of L and : L × L → L is called the meet operator of L. Definition 2.2.3 (Complete lattice). A lattice (L, , , , ⊥, ) is a complete lattice if every subset S ⊆ L has a least upper bound S and a greatest lower bound S in L. The least element of L, called bottom, is denoted as ⊥ = L and the greatest element of L, called top, is denoted as = L.

Complete Lattices

Example 2.2.1. For any set X, the set 2 X of all subsets of X, also called the powerset of X, is a complete lattice (2 X , ⊆, ∪, ∩, ∅, X) for inclusion. For example, the powerset 2 Z of Z is a complete lattice (2 Z , ⊆, ∪, ∩, ∅, Z).

Fixpoint Theorems

Monotonic Functions and Tarski's Fixpoint Theorem

Definition 2.2.4 (Monotonic function). Let (D 1 , 1 ) and (D 2 , 2 ) be two partially ordered sets. A function F : D 1 → D 2 from D 1 to D 2 is monotonic if it satisfies the following property:

∀a, b ∈ D 1 , a 1 b ⇒ F (a) 2 F (b)
Definition 2.2.5 (Fixpoint). Let (D, ) be a partially ordered set. Let F : D → D be a function on D. An element x ∈ D is a pre-fixpoint of F if x F (x). An element x ∈ D is a post-fixpoint of F if F (x) x. An element x ∈ D is a fixpoint of F if F (x) = x. We denote as lfp(F ) the least fixpoint of F and as gfp(F ) the greatest fixpoint of F if they exist.

Tarski's fixpoint theorem ensures the existence of fixpoints for a monotonic function on a complete lattice, such that the set fix(F ) of such fixpoints is itself a complete lattice. The set fix(F ) being a complete lattice, it has a least element and a greatest element. Thus a monotonic function F on a complete lattice L has always a least fixpoint lfp(F ) and a greatest fixpoint gfp(F ) in L.

Theorem 2.2.1 (Tarski's fixpoint theorem). Let (L, , , , ⊥, ) be a complete nonempty lattice and F : L → L be a monotonic function on L. The set fix(F ) of fixpoints of F is a non-empty complete lattice:

lfp(F ) = {x ∈ L | F (x) x} gfp(F ) = {x ∈ L | x F (x)}

Continuous Functions and Kleene's Theorem

Tarski's fixpoint theorem ensures the existence of fixpoints for monotonic functions on complete lattices. In practice, we use Kleene's fixpoint theorem for continuous functions which gives a method to compute fixpoints using Kleene iterations.

Definition 2.2.6 (Continuous function). Let (D, , , , ⊥, ) be a complete lattice. A function f : D → D is Scott-continuous if it preserves least upper bounds:

∀X ⊆ D, f ( X) = f (X)
Remark: a continuous function on a complete lattice is necessarily monotonic.

Theorem 2.2.2 (Kleene's fixpoint theorem). Let F : D → D be a continuous function on a complete lattice (D, , , , ⊥, ). The extreme fixpoints of F exist:

lfp(F ) = n≥0 F n (⊥) gfp(F ) = n≥0 F n ( ) Chapter 2
Program Analysis by Abstract Interpretation Example 2.1.1 (continued) We apply Kleene's fixpoint theorem to our example by trying to compute the least solution of the system of semantic equations:

X 0 = Z X 1 = X 0 [i := 0] X 2 = X 1 ∪ X 4 X 3 = (X 2 ∩ (i < 100))[i := i + 1] X 4 = X 3 X 5 = X 2 ∩ (i ≥ 100) X 6 = X 5
The solution is be computed in the complete lattice (2 Z , ⊆, ∪, ∩, ∅, Z) of possible valuations for i. According to Kleene's theorem, we start from (X k = ∅) k=0.. [START_REF] André | Semantics of SyncCharts[END_REF] . At the first iteration, we get:

X 0 = Z X 1 = {0} X 2 = {0} X 3 = {1} X 4 = {1} X 5 = ∅ X 6 = ∅
We can compute some more steps:

We can foresee that this kind of computation does not terminate in general for arbitrary sets of integers. Also, it is well-known that arbitrary sets of integers are not machinerepresentable. Thus it entails two main necessities: the use of a decidable, machinerepresentable abstraction of sets of states and a way to enforce the convergence of fixpoint computations. This is the main goal of abstract interpretation.

Concrete and Abstract Domains

For the reachable states of a program, the most precise property of interest is the least fixpoint of collecting semantics, which is not computable in general or would result in computations over a very complex domain which would track precisely all the aspects of a program implementation, such as the state of registers, the stack and the heap. Such a domain is called a concrete domain. The concrete semantics can be approximated by an abstract semantics with values belonging to an abstract domain. The elements of the concrete domain are said to be approximated by the elements of the abstract domain.

Abstract Domains

Definition 2.3.1 (Galois Connection). Let (D 1 , 1 ) and (D 2 , 2 ) be two partially ordered sets. A Galois connection from D 1 to D 2 is a pair (α, γ) of functions such that α : D 1 → D 2 is called the abstraction function and γ : D 1 → D 1 is called the concretization function satisfying the following property:

α(d 1 ) 2 d 2 ⇔ d 1 1 γ(d 2 )
Definition 2.3.2 (Abstract Domain). Let (C, C , C , C ) be a lattice of elements to be abstracted considered as the concrete domain. An abstract domain is a lattice (D, , , ) related to C by a Galois connection (α, γ) with α : C → D and γ : D → C.

Example 2.3.1 (Interval abstract domain). In Example 2.1.1, the concrete domain is the complete lattice (2 Z , ⊆, ∪, ∩, ∅, Z). A possible abstract domain is the complete lattice of intervals of integers (I, , , , ⊥, (-∞, +∞)) defined as:

I = (Z ∪ {-∞}) × (Z ∪ {+∞}) ∀(a, b), (c, d) ∈ I, (a, b) (c, d) ⇔ c ≤ a ∧ b ≤ d (a, b) (c, d) = (inf(a, c), sup(b, d)) (a, b) (c, d) = (sup(a, c), inf(b, d))
We assume that (a, b) = ∅ for a > b. The Galois connection (α, γ) between 2 Z and I is:

∀X ⊆ Z, α(X) = (inf(X), sup(X)) if X = ∅ ⊥ otherwise ∀(a, b) ∈ I, γ((a, b)) = [a, b] if a ≤ b ∅ otherwise

Fixpoint Computation

The set of reachable states is the least fixpoint of a function F over a concrete domain D. The elements of the concrete domain may not be representable by machine and the concrete function F may not be computable. Instead, we compute the least fixpoint of a sound approximation F : D → D of F over an abstract domain D .

∀d ∈ D , F (γ(d )) D γ(F (d ))
The fixpoint transfer theorem guarantees that the least fixpoint of F over the abstract domain D is a sound approximation of the least fixpoint of F over the concrete domain D. If F is continuous, it follows from Kleene's Fixpoint Theorem that the least fixpoint lfp(F ) of F is the limit of the Kleene's sequence (x i ) i≥0 defined as:

x 0 = ⊥ x i+1 = F (x i ) Chapter 2
Program Analysis by Abstract Interpretation Example 2.1.1 (continued) We want to compute a solution of the system of equations of our program, in the complete lattice of intervals of integers. The system of abstract semantic equations over I is defined as:

X 0 = X 1 = X 0 [i := 0] X 2 = X 1 X 4 X 3 = (X 2 (i < 100))[i := i + 1] X 4 = X 3 X 5 = X 2 (i ≥ 100) X 6 = X 5
We compute a Kleene's sequence starting with (X k = ⊥) k=0..6 . We get:

X 0 = (-∞, +∞) X 1 = (0, 0) X 2 = (0, 0) X 3 = (1, 1) X 4 = (1, 1) X 5 = ⊥ X 6 = ⊥
We can compute some more steps:

X 0 = (-∞, +∞) X 1 = (0, 0) X 2 = (0, 1) X 3 = (1, 2) X 4 = (1, 2) X 5 = ⊥ X 6 = ⊥ X 0 = (-∞, +∞) X 1 = (0, 0) X 2 = (0, 2) X 3 = (1, 3) X 4 = (1, 3) X 5 = ⊥ X 6 = ⊥ X 0 = (-∞, +∞) X 1 = (0, 0) X 2 = (0, 3) X 3 = (1, 4) X 4 = (1, 4) X 5 = ⊥ X 6 = ⊥
A Kleene's sequence in the lattice of intervals of integers does not terminate in general. The Kleene's fixpoint theorem gives a method to compute least fixpoints of a continuous function over an abstract domain, by recasting them as limits of possibly infinite iterations. However, we have no way to compute limits of infinite iterations in general.

Convergence

A Kleene's sequence is trivially converging when the abstract domain is a finite lattice, such as the lattice of signs or the lattice Z k of integers representable on k bits, or if it does not contain any infinite strictly increasing sequence. This is not the case for many interesting abstract domains such as the lattice I of intervals of integers. The convergence of a Kleene's sequence can not be guaranteed in general. A solution is to extrapolate the limit of a Kleene's sequence using a widening operator, which guarantees a finite computation converging to an upper approximation of the exact limit of the sequence. Definition 2.3.4 (Widening operator). Let (D , , , , ⊥, ) be a complete lattice. A widening operator is a binary operator ∇ : D × D → D satisfying the following properties:

1. ∀x, y ∈ D , x y x∇y 2. For every increasing sequence (x k ) k≥0 , the increasing sequence (y k ) k≥0 defined as follows:

y 0 = x 0 y k+1 = y k ∇x k is ultimately stationary: ∃ ∈ N, ∀k ≥ , y k+1 = y k .
For a discussion on the design of widening operators, see [START_REF] Cousot | Comparing the Galois connection and widening/narrowing approaches to abstract interpretation[END_REF] and [START_REF] Cortesi | Widening operators for abstract interpretation[END_REF].

Theorem 2.3.2 (Fixpoint extrapolation). Let F : D → D be a continuous function on an abstract domain (D , , , , ⊥, ). Let ∇ : D × D → D be a widening operator on D . The increasing sequence (X k ) i≥0 defined as:

X 0 = ⊥ X k+1 = X k ∇F (X k )
is ultimately stationary: ∃ ∈ N, ∀k ≥ , X k+1 = X k . The limit X ∇ of the increasing sequence (X k ) k≥0 is a post-fixpoint of F and thus a sound approximation of the least fixpoint lfp(F ) with lfp(F ) X ∇ . When X ∇ is not a fixpoint of F , the solution given by the limit X ∇ of the increasing sequence can be improved by computing a decreasing sequence using a narrowing operator. Definition 2.3.5 (Narrowing Operator). Let (D , , , , ⊥, ) be a complete lattice. A narrowing operator is a binary operator : D × D → D satisfying the following properties:

1. ∀x, y ∈ D , y x y x 2. For every decreasing sequence (t k ) k≥0 , the decreasing sequence (z k ) k≥0 defined as:

z 0 = t 0 z k+1 = z k t k is ultimately stationary: ∃ ∈ N, ∀k ≥ , z k+1 = z k .
The decreasing sequence (Y k ) k≥0 starting with the limit X ∇ of the increasing sequence is defined as:

Y 0 = X ∇ Y k+1 = Y k F (Y k )
Every term of the decreasing sequence is a post-fixpoint of F and a sound approximation of the least fixpoint. We can stop the decreasing sequence arbitrarily after any number of steps, without waiting for convergence, and still get a correct approximation of lfp(F ). In practice, we can compute a decreasing sequence without using any narrowing operator, by just applying F for a finite number of terms as follows:

Y 0 = X ∇ Y k+1 = F (Y k )
We denote as X ∇ the limit of the decreasing sequence. It is decreasing since F is monotonic and its terms are post-fixpoints of F .

Example 2.3.2 (Widening and narrowing on intervals). The following operator ∇ : I × I → I on intervals of integers is a widening operator:

∀(a, b), (c, d) ∈ I, (a, b)∇(c, d) = a if a ≤ c -∞ otherwise , b if b ≥ d +∞ otherwise
The following operator : I × I → I on intervals of integers is a narrowing operator:

∀(a, b), (c, d) ∈ I, (a, b) (c, d) = c if a = -∞ a otherwise , d if b = +∞ b otherwise Example 2.1.1 (continued)
We compute an approximation of the sets of reachable valuations of i in the interval abstract domain I. We define a system of abstract fixpoint equations where the widening operator is applied on X 2 :

X 0 = X 1 = X 0 [i := 0] X 2 = X 2 ∇(X 1 X 4 ) X 3 = (X 2 (i < 100))[i := i + 1] X 4 = X 3 X 5 = X 2 (i ≥ 100) X 6 = X 5
We compute an increasing sequence as follows:

X 0 X 1 X 2 X 3 X 4 X 5 X 6 [-∞, +∞] ⊥ ⊥ ⊥ ⊥ ⊥ ⊥ [-∞, +∞] [0, 0] [0, 0] [1, 1] [1, 1] ⊥ ⊥ [-∞, +∞] [0, 0] [0, +∞] [1, 100] [1, 100] [100, +∞] [100, +∞]
The increasing sequence has converged. It gives the approximation [0, +∞] for the set of reachable valuations of i at the head of the while loop at node 2. This post-fixpoint can be improved by computing a decreasing sequence: The decreasing sequence converges in a single iteration and gives the invariant i ∈ [0, 100] at the head of the while loop.

X 0 X 1 X 2 X 3 X 4 X 5 X 6 [-∞, +∞] [0, 0] [0, +∞] [1,

Choice of Widening Nodes

The increasing and the decreasing sequence are computed in a chaotic way, by propagating abstract values along the paths of the CFG. Since the widening operator loses information, it is only applied to a selected set W of widening nodes cutting each loop of the CFG. In example 2.1.1, widening was applied on X 2 which is associated to the head ν 2 of the while loop.

Since finding a minimal cutting set W is an NP-complete problem, the set of widening nodes is classically chosen heuristically using the method of strongly connected subcomponents proposed by Bourdoncle [START_REF] Bourdoncle | Sémantiques des langages imperatifs d'ordre superieur et interpretation abstraite[END_REF][START_REF] Bourdoncle | Efficient chaotic iteration strategies with widenings[END_REF]. The method uses recursively Tarjan's algorithm [START_REF] Tarjan | Depth-first search and linear graph algorithms[END_REF] to find the strongly connected components (SCC) of a directed graph and their entry nodes. The entry nodes are the targets of back edges, thus they are all junction nodes. Bourdoncle's method adds the entry node of each SCC to W, then removes them from the graph and recursively applies Tarjan's algorithm to the rest of each SCC. The result is a hierarchy of strongly connected subcomponents, each of which is cut by a junction node in W.

Numerical Abstract Domains

We present in this section some numerical abstract domains abstracting subsets of K n for K ∈ {Z, Q, R}.

Affine Equalities

An affine relationship is an equality of the form a j x j = b i between a linear combination of numerical variables x j and a constant b i . M. Karr [START_REF] Karr | Affine relationships among variables of a program[END_REF] introduced the abstract domain of affine equalities to discover all valid affine equalities among the variables of a program. The domain representation and its operations are based on linear algebra.

A set of affine equalities over n variables determines an affine subspace and can be represented by an m × n matrix M , where m ≤ n, along with an m-dimensional column vector C. Each row of M and C represents an affine equality. The pair (M, C) is called the constraint representation of the set of affine equalities. The domain of affine equalities is a relational domain of finite height, which does not contain infinite strictly increasing sequences.

Zones

Zones are subsets of K n represented by sets of constraints of the form x i -x j ≤ c or ±x i ≤ c where c ∈ K is a constant and x i , x j are numerical variables. Zones were proposed in [START_REF] Dill | Timing assumptions and verification of finite-state concurrent systems[END_REF][START_REF] Yovine | Model checking timed automata[END_REF] for the model-checking of timed automata and were later adapted to abstract interpretation [START_REF] Miné | A new numerical abstract domain based on difference-bound matrices[END_REF].

Representation

A zone is represented by a potential graph with nodes labeled by numerical variables. There is an edge from a node labeled by a variable x i to a node labeled by a variable x j with weight c ∈ K if there exists a constraint x i -x j ≤ c. Unary constraints of the form x i ≤ c are rewritten as binary constraints x i -x 0 ≤ c with a phantom variable x 0 which is always equal to the constant zero. A potential graph is represented classically by its adjacency matrix called a Difference Bound Matrix (DBM).

Operations on Zones

A DBM is normalized by computing its transitive closure by the Floyd-Warshall algorithm. The equality or inclusion of two zones is tested by first normalizing their respective DBMs and then comparing the values of the normalized DBMs.

Zones are closed under union and the least upper bound of two DBMs is obtained by merging the two graphs and normalizing the resulting adjacency matrix. The greatest lower bound of two DBMs m 1 and m 2 is computed by taking, for each pair (x i , x j ) of variables, the minimum of the weights associated to the edge (x i , x j ) in m 1 and in m 2 . It gives the smallest constant c such that x i -x j ≤ c.

The widening m∇n of two DBMs m and n is defined as:

(m∇n) i,j = m i,j if n i,j ≤ m i,j +∞ otherwise
Chapter 2

Program Analysis by Abstract Interpretation

The narrowing m n of two DBMs m and n is defined as:

(m n) i,j = n i,j if n i,j = +∞ m i,j otherwise
Operations on DBMs have a O(n 3 ) complexity in the number of numerical variables due to the transitive closure algorithm used for normalization.

Octagons

The octagons abstract domain presented in [START_REF] Miné | The octagon abstract domain[END_REF][START_REF] Miné | The octagon abstract domain[END_REF] is an extension of zones to sets of constraints of the form ±x i ± x j ≤ c where x i , x j are numerical variables and c ∈ K is a constant.

Representation

We consider that variables come in two flavors, each variable x i comes in a positive form x + i and in a negative form x - i . A constraint of the form x i + x j ≤ c can be represented by the pair of potential constraints x + i -x - j ≤ c and x + j -x - i ≤ c involving the positive and the negative forms of the original variables x i and x j . More generally, any set of constraints of the form ±x i ± x j ≤ c can be represented by a DBM using the following translation scheme:

Octagon constraint Potential constraints x i -x j ≤ c x + i -x + j ≤ c, x - j -x - i ≤ c -x i -x j ≤ c x - i -x + j ≤ c, x - j -x + i ≤ c x i + x j ≤ c x + i -x - j ≤ c, x + j -x - i ≤ c x i ≤ c x + i -x - i ≤ 2c x i ≥ c x - i -x + i ≤ -2c

Operations

The DBM representation of octagons is normalized using a variant of the Floyd-Warshall algorithm called the strong closure algorithm [START_REF] Miné | Weakly Relational Numerical Abstract Domains[END_REF].

In a similar way to zones, the emptiness of an octagon is tested as a side-product of the strong closure algorithm. An octagon represented by a normalized DBM m is not empty if there exists variables x i , x j such that m i,j = 0. The inclusion of two octagons is tested by comparing the values in their respective normalized DBMs.

The intersection of two octagons is computed using the intersection of their DBMs. The least upper bound of two octagons is the least upper bound of their normalized DBMs.

The matrix-based representation of zones and octagons using DBMs is amenable to fast parallel implementations. An implementation of the octagon abstract domain on GPUs (Graphics Processing Unit) is described in [START_REF] Banterle | A fast implementation of the octagon abstract domain on graphics hardware[END_REF].

Complexity and Expressivity

Zones and octagons are able to represent sets of constraints of the form x i -x j ≤ c for zones and ±x i -±x j ≤ c for octagons. Operations have a O(n 3 ) time complexity in the worst-case as they are based on the Floyd-Warshall algorithm. These domains are not able to represent arbitrary linear relations of the form a j x j ≥ b i between numerical variables, whereas linear relations can be expressed in their full generality by the more costly abstract domain of convex polyhedra.

Convex Polyhedra

The convex polyhedra abstract domain was proposed in [START_REF] Cousot | Automatic discovery of linear restraints among variables of a program[END_REF][START_REF] Halbwachs | Détermination automatique de relations linéaires vérifiées par les variables d'un programme[END_REF] to discover sets of linear relations of the form a j x j ≥ b i between program variables where the x j are numerical variables and the a j and b i are constants. The set of solutions of a system of linear relations is a convex polyhedron.

Representations of Convex Polyhedra

A convex polyhedron P can be represented either as a set of linear constraints:

P = {x = (x 1 , ..., x n ) | 1≤i≤m 1≤j≤n a j x j ≥ b i } = {x ∈ Z n | Ax ≥ B}
or as a system of generators:

P = { s i ∈V λ i s i + r j ∈R µ j r j | λ i ≥ 0 ∧ λ i = 1 ∧ µ j ≥ 0}
where V is a finite set of vertices and R is a finite set of rays. The pair (A, B) is called a system of constraints of P and (V, R) is called a system of generators of P . The system of constraints (A, B) represents the polyhedron P by giving the constraints satisfied by the points included in P . The system of constraints is equivalently given in matrix form as AX ≥ B where X is an n-row vector of variables x 1 , .., x n .

The system of generators (V, R) represents a convex polyhedron P as the set of all points which are sums of a convex combination s i ∈V λ i s i of vertices in S and of a positive combination r j ∈R µ j r j of rays in R.

A generator G satisfies a linear constraint

A i X ≥ B i if A i • G ≥ B i .
A system of generators (V, R) satisfies a system of constraints (A, B) if all vertices in V and rays in R

satisfy the constraints AX ≥ B. A generator G saturates a linear constraint A i X ≥ B i if A i • G = B i .
The lattice of convex polyhedra is not complete since the convex hull of an infinite set of polyhedra is not necessarily a polyhedron, as it can be, for example, a disk. However, it is a sublattice of the complete lattice of convex sets. An analysis using convex polyhedra involves only a finite number of operations, due to the use of widening, thus it is guaranteed to stay within the sublattice of convex polyhedra.

Operations on Convex Polyhedra

Conversion of Representations

A system of constraints or a system of generators is said to be minimal if no constraint or generator can be removed without changing the represented set of points. Chernikova's algorithm [START_REF] Chernikova | Algorithm for discovering the set of all the solutions of a linear programming problem[END_REF], later improved by Le Verge [START_REF] Verge | A note on Chernikova's algorithm[END_REF], constructs the minimal system of generators equivalent to a given system of constraints and conversely.

Intersection

The intersection of two convex polyhedra P and Q is the convex polyhedron P Q computed simply as the conjunction of the sets of constraints of P and Q.

Convex Hull

The union of two convex polyhedra is not convex in general. Instead, we compute the convex hull of convex polyhedra, which is the smallest convex polyhedron containing both polyhedra. The convex hull of two convex polyhedra P and Q is denoted as P Q. Every point in the convex hull P Q is a convex combination of the generators of P and Q.

The convex hull is computed by joining together the generators of P and Q. This can generate redundant generators and a pass of Chernikova's algorithm should be applied to obtain a minimal representation of the result.

Inclusion and Equality

The inclusion of two convex polyhedra P and Q is tested by checking if the system of generators (S, R) of P satisfies the system of constraints of Q. The equality of two convex polyhedra P and Q is checked by testing the double inclusion of P in Q and symmetrically of Q in P .

Emptiness Test

An empty convex polyhedron has an empty system of generators (∅, ∅) and infinitely many constraint representations. The emptiness of a convex polyhedron P can be tested by checking the emptiness of a minimal generator representation of P .

Widening

The classical widening operator on convex polyhedra was introduced in [START_REF] Halbwachs | Détermination automatique de relations linéaires vérifiées par les variables d'un programme[END_REF]. The widening P ∇Q of a convex polyhedron P by a convex polyhedron Q is defined roughly as removing the constraints of P which are not satisfied by Q. The result is an extrapolation of both P and Q as it contains both polyhedra. More precisely, the widening P ∇Q is defined as the set of constraints of P which are satisfied by Q and the constraints of Q which are mutually redundant with constraints of P . Two constraints are mutually redundant if they saturate the same set of generators, either vertices or rays.

When the dimension of P is less than the dimension n of the space, the constraints of P are rewritten to maximize the number of constraints of Q which are mutually redundant with constraints of P . The aim is to maximize the number of constraints of Q which are kept in P ∇Q.

Example 2.4.1. We give a simple example of widening over convex polyhedra. Let

P = (i ≥ 0 ∧ i ≤ 0 ∧ n ≥ 0) and Q = (i ≥ 0 ∧ i ≤ 1 ∧ i ≤ n). The widening of P by Q is P ∇Q = (i ≥ 0 ∧ i ≤ n).
Many proposals concerning the improvement of widening operators have been made, especially for the convex polyhedra abstract domain [START_REF] Bagnara | Precise widening operators for convex polyhedra[END_REF].

Widening with thresholds [START_REF] Halbwachs | Delay analysis in synchronous programs[END_REF][START_REF] Halbwachs | Verification of real-time systems using linear relation analysis[END_REF][START_REF] Blanchet | Design and implementation of a special-purpose static program analyzer for safety-critical real-time embedded software[END_REF] consists in choosing constraints, from conditions appearing in the program or some propagation of them [START_REF] Lakhdar-Chaouch | Widening with thresholds for programs with complex control graphs[END_REF], as candidate limits to the widening, which has the effect of relaxing bounds of variables more gradually instead of moving them to infinity. Widening with landmarks follows a similar idea where the selection of constraints is made dynamically [START_REF] Simon | Widening polyhedra with landmarks[END_REF]. Widening with a care set [START_REF] Wang | Using counterexamples for improving the precision of reachability computation with polyhedra[END_REF] and interpolated widening [START_REF] Gulavani | Automatically refining abstract interpretations[END_REF] make use of a proof objective.

Another improvement of widening is limited widening, defined as the intersection (P ∇Q) A of the classical widening P ∇Q by a limiting abstract value A. For limited widening to be sound, the limiting value A must be an invariant at the node where the limited widening is applied, such as, for example, a precondition of the procedure. An increasing sequence using limited widening is not guaranteed to be converging in general. For the convex polyhedra abstract domain, we can make the same argument as for the termination of the classical widening, that either the number of constraints in the result decreases or the dimension of the resulting convex polyhedron increases.

Complexity

Each operation on convex polyhedra have a preferred representation. Some operations need either the system of constraints, such as intersection, or the system of generators, for the convex hull, or both for the inclusion test. Converting one representation to the other can be costly, producing a representation which is O(2 n ) in size with respect to the original representation. This is particularly the case for an axis-aligned n-dimensional hypercube, where n variables have bounds with no relations between the variables, represented by 2n constraints and a system of generators with 2 n vertices. In order to alleviate the costs due to the double representation of convex polyhedra, a constraint-only representation was proposed in [START_REF] Benoy | Computing convex hulls with a linear solver[END_REF][START_REF] Fouilhé | Efficient generation of correctness certificates for the abstract domain of polyhedra[END_REF][START_REF] Alexis | Revisiting the abstract domain of polyhedra : constraints-only representation and formal proof[END_REF][START_REF]New Algorithmics for Polyhedral Calculus via Parametric Linear Programming[END_REF][START_REF] Maréchal | Efficient elimination of redundancies in polyhedra by raytracing[END_REF].

Advanced techniques

In this section, we present some advanced techniques to improve the precision of properties computed using abstract interpretation.

Guided Static Analysis

Guided static analysis [START_REF] Gopan | Lookahead widening[END_REF][START_REF] Gopan | Guided static analysis[END_REF] was proposed to improve the precision of properties of loops with multiple phases having very different behaviors which can depend on nondeterministic choices.

We remember the set of program points which are reachable before the first application of the widening operator during the increasing sequence. The widening operator is applied and the increasing sequence is then computed only on the restricted program consisting of the reachable program points before widening. When the increasing sequence has converged, the decreasing sequence is computed on the program restriction to improve the result of the increasing sequence.

A new program restriction is obtained at the end of the decreasing sequence, by taking into account the program locations which are now reachable and which were previously ignored. An increasing sequence, followed by a decreasing sequence, is restarted on the newly derived program restriction.

More and more program points are added to the program restriction in a succession of increasing and decreasing sequences, until the entire program is considered. A guided static analysis is converging since there is only a finite number of program locations.

Intuitively, the guided static analysis approach discovers distinct loop phases and analyzes them successively, avoiding the loss of precision occurring in a standard analysis due to the simultaneous consideration of possibly very different behaviors.

Example 2.5.1. We consider the program shown in Figure 2.4. A standard Linear Relation Analysis applies widening at node ν 1 and gives the following abstract value for ν 1 after one iteration of the increasing sequence:

x + y = 50 ∧ x ≥ 0
The node ν 3 becomes reachable and is taken into account by the analysis, causing a tremendous loss in precision at the join node ν 4 . When the analysis has converged, the loop invariant obtained at ν 1 is: if y <= 0 then break; end; end;

x + y ≤ 50 ∧ y ≥ 1
x := 0 y := 50

x < 50? The abstract value obtained after the while loop at ν 7 is:

x := x + 1 y := y -1 x ≥ 50? x := x -1 y := y -1 y ≥ 1? y ≤ 0? ν 0 ν 1 ν 2 ν 3 ν 4 ν 5 ν 6 ν 7
y = 0 ∧ x ≤ 50
A guided static analysis first computes an increasing sequence followed by a decreasing sequence in which the dashed program edges are ignored. A more precise loop invariant is obtained at node ν 1 :

x + y = 50 ∧ 0 ≤ x ≤ 49

The node ν 3 remains unreachable when analyzing the entire program. We obtain the following property at ν 7 after the while loop:

x = 50 ∧ y = 0
We discovered the equality constraint x = 50 at node ν 7 with the guided static analysis whereas the classical Linear Relation Analysis only found the inequality constraint x ≤ 50.

Trace Partitioning

A way to avoid the loss of precision occurring at join nodes is to keep separate the abstract values obtained at conditional branches. Trace partitioning [START_REF] Mauborgne | Trace partitioning in abstract interpretation based static analyzers[END_REF][START_REF] Rival | The trace partitioning abstract domain[END_REF] was proposed to abstract sets of program traces.

The idea is to duplicate abstract states and to keep them separate by associating an abstract value to the set of program edges that a trace goes through to obtain that value. Each time such a disjunction is introduced, the size of the abstract graph is doubled.

Heuristics are given to choose dynamically the nodes where the splitting of abstract states is applied and when nodes in the graph of abstract states can be merged.

Chapter 2

Program Analysis by Abstract Interpretation Example 2.5.2. We consider in this example the program fragment presented in Figure 2.5a which computes the absolute value of a variable x. We are interested in proving the absence of division by zero at node ν 5 . We can prove the property by distinguishing all paths such as in Figure 2.5b, since we have s = -1 at node ν 5 , {(v 1 , v 2 )} and s = 1 at node ν 5 , {(v 1 , v 3 )}. The property can still be proven in Figure 2.5c if we merge the paths at nodes ν 5 and ν 6 .

x < 0? s := -1 x ≥ 0? s := 1 z := x/s ν 1 ν 2 ν 3 ν 4 ν 5 ν 6 (a) ν 1 , ∅ ν 2 , {(ν 1 , ν 2 )} ν 3 , {(ν 1 , ν 3 )} ν 4 , {(ν 1 , ν 2 )} ν 4 , {(ν 1 , ν 3 )} ν 5 , {(ν 1 , ν 2 )} ν 5 , {(ν 1 , ν 3 )} ν 6 , {(ν 1 , ν 2 )} ν 6 , {(ν 1 , ν 3 )} (b) ν 1 , ∅ ν 2 , {ν 1 .ν 2 } ν 3 , {ν 1 .ν 3 } ν 4 , {ν 1 .ν 2 } ν 4 , {ν 1 .ν 3 } ν 5 , ∅ ν 6 , ∅ (c)

Chapter 3

Interprocedural Analysis: A State of the Art

The Origins of Interprocedural Analysis

Interprocedural analysis originated in side-effects analysis for compiler optimization from works of Spillman [START_REF] Spillman | Exposing side-effects in a PL/I optimizing compiler[END_REF], Allen [START_REF] Allen | Interprocedural analysis and the information derived by it[END_REF] and Barth [12]. Frances E. Allen coined the term of interprocedural analysis in 1974 and introduced some of the foundational concepts of interprocedural analysis in [START_REF] Allen | Interprocedural analysis and the information derived by it[END_REF]. At that time, early works on global dataflow analysis [START_REF] Kildall | A unified approach to global program optimization[END_REF] were considering whole programs, represented by a single global control-flow graph, without any particular focus on the procedural structure of programs.

Programs as Collections of Procedures

Programs can be seen as collections of procedures K = {p 1 , .., p n } possibly referencing each other. The references between the procedures can be expressed as a directed graph C = (N, E) of nodes n i ∈ N and edges (e i , e j ) ∈ E as follows: 1. Each node n i represents a procedure p i and the set of nodes N is in a one-to-one correspondence with K. 2. Each edge (e i , e j ) ∈ E represents one or more references from the procedure p i to the procedure p j . Such a graph C is termed the call graph of the program.

Cycles in the call graph indicate the presence of recursive procedures. A self-loop in the call graph denote a simple recursive procedure referencing itself, whereas a non-trivial cycle denote a set of mutually recursive procedures.

A procedure p i can reference a procedure p j by a call statement to p j . Other kinds of procedure referencing are possible in languages allowing the explicit manipulation of references or pointers to procedures, such as function pointers in C-based languages.

We should note that a call graph is not a control flow graph and does not represent returns from procedure calls.

Frances Allen gives in [START_REF] Allen | Interprocedural analysis and the information derived by it[END_REF] a classical algorithm for the construction of the call graph of a collection of procedures.

Chapter 3

Interprocedural Analysis: A State of the Art

Completeness of a Collection of Procedures

Incomplete programs are programs where the implementation is only partially known statically, prior to their concrete execution. It encompasses programs with dynamicallylinked libraries, which can be potentially different for each concrete execution platform, and programs with reflective features, capable of modifying their own structure at runtime, such as dynamic code generation in Lisp dialects or Javascript. Definition 3.1.1 (Completeness of a set of procedures). A set K of procedures is complete if there is a unique initial entry procedure p 1 in K and if p i ∈ K references a procedure p j then p j ∈ K.

We consider implicitly complete sets of procedures. The adaptation to incomplete programs is considered to be outside the scope of this work.

Top-down and Bottom-up Analyses

We define a partial order relation < K called an invocation order from the call graph C where n i < K n j if n i is a direct predecessor of n j in the call graph C. The invocation order embodies the notion of interprocedural dependency between procedures. We define conversely the inverse invocation order < K on procedures where n i < K n j if n j < K n i , which can be seen as a sort of bottom-up view of the call graph.

Interprocedural analyses can be categorized according to the order in which procedures are traversed. In a top-down analysis, procedures are analyzed according to the invocation order < K from callers to callees, whereas in a bottom-up analysis, procedures are analyzed according to the inverse invocation order < K from the callees up to the callers, usually by computing summaries of procedures. Recently, hybrid analyses [START_REF] Zhang | Hybrid top-down and bottom-up interprocedural analysis[END_REF] have been devised, in an attempt to combine the strengths of bottom-up analyses and top-down analyses.

In this thesis, we are interested in bottom-up approaches since procedures are analyzed only once, regardless of the number of calling contexts and in possibly much smaller abstract environments, allowing a modular analysis with potential scalability improvements for numerical analyses by abstract interpretation such as Linear Relation Analysis.

The next contribution of historical significance with regards to its influence on many posterior approaches is the work of M. Sharir and A. Pnueli in [START_REF] Sharir | Two approaches to interprocedural data flow analysis[END_REF] which introduced the functional approach and the call strings approach for distributive data flow frameworks.

The Functional Approach

The functional approach computes data flow properties of programs using summaries of procedures, either from the bottom-up composition of individual propagation functions or by propagating data flow properties in a top-down fashion and by tabulating the properties obtained at the exit node of a procedure with the associated property at entry.

Data Flow Frameworks

The functional approach of Sharir and Pnueli considers finite data flow properties in a distributive data flow framework. Definition 3.1.2 (Data flow framework). A data flow framework (L, F ) is made of a semilattice of data flow properties (L, , , ⊥, ) and a set F ⊆ L → L of monotonic propagation functions on L.

The operation of the semilattice L is denoted by the meet operator also called the data flow confluence operator.

The set F of propagation functions contains the identity function on L and is closed under the meet operation of L and functional composition.

∀f ∈ F, ∀x, y ∈ L, f (x y) = f (x) f (y)
We use the control flow graph representation of procedures and we consider that each procedure has a control-flow graph G p = (V p , E p ) where V p is the set of the basic blocks of procedure p and E p is the set of edges. The root block of the procedure is denoted by r p .

In the data flow framework (L, F ), a propagation function f (n i ,n j ) : L → L is associated to each edge (n i , n j ) ∈ E p in the CFG of each procedure p. It represents the transformation of the data flow properties when control passes from the beginning of basic block n i to the end of n i and then to the beginning of basic block n j .

Example 3.1.1 (Reaching definitions). Reaching definitions is a classical intraprocedural data flow analysis computing the set of the variable definitions v := e reachable at a given basic block n i ∈ G p of a procedure p with no assignment to v between n i and a definition of v. It is represented by a distributive data flow framework (L, F ) as follows:

1. The semilattice of data flow properties is L = P(Def p ) where Def p is the set of the variable definitions in p. The semilattice is partially ordered by set inclusion ⊆ and the semilattice operation is set union. 2. The set F ⊆ L → L contains propagation functions f (n i ,n j ) : L → L for each edge (n i , n j ) ∈ E p in the CFG of p which are defined as:

f (n i ,n j ) (d) = GEN(n i ) ∪ (d -KILL(n i ))
where GEN(n i ) is the set of variable definitions in a basic block n i :

GEN(n i ) = { (v := e) ∈ Def p | (v := e) ∈ n i }
and KILL(n i ) is the set of definitions where the variable v is assigned in n i :

KILL(n i ) = {(v := e 1 ) ∈ Def p | ∃(v := e 2 ) ∈ n i }
The set R n j of reaching definitions at the beginning of a basic block n j is the least solution of the following system of equations:

∀n j ∈ N p , R rp = ∅ R n j = (n i ,n j )∈Ep f (n i ,n j ) (R n i )
Constant propagation can be extracted from the results of reaching definitions. A variable v is always equal to a constant c at the beginning of a basic block n i if a unique definition v := c of v is reachable at n i , with (v := c) ∈ R n i .

Chapter 3

Interprocedural Analysis: A State of the Art It can be confusing that the operation of the semilattice of data flow properties is denoted by the meet operator but it is common practice in data flow analysis. The operator is instantiated in each particular analysis, such as set union for reaching definitions in Example 3.1.1.

Interprocedural Analysis over a Distributive Data Flow Framework

The functional approach considers data flow frameworks in the interprocedural case.

Let (L, F ) be a distributive data flow framework. For each entry block or root block r p of a procedure p and each basic block n i of p, we add propagation functions ϕ (rp,n i ) : L → L to the function space F which represent the propagation of data flow properties in p from r p to n i . They are defined by the following set of equations:

∀x ∈ L, ϕ (rp,rp) (x) = x ∀n i ∈ N p -{r p }, ϕ (rp,n i ) (x) = (n i ,n j )∈Ep h (n i ,n j ) (ϕ (rp,n i ) (x)) h (n i ,n j ) (x) = f (n i ,n j ) (x)
if n i is not a call block eq∈Exitq ϕ (rq,eq) (x) if n i ends with a call to procedure q where h(n i , n j ) denotes the propagation of properties from a basic block n i to its successor n j . If n i ends with a call to a procedure q, properties are propagated in q and the returned property is the meet of the properties obtained at the exit blocks of q. We compute the maximal fixed point solution of the following set of equations:

X (main,r main ) = ⊥ X (q,rq) = X (p,c) for each procedure p calling q in a basic block c X (p,n i ) = ϕ (rp,n i ) (X (p,rp) )

The Call Strings Approach

The call strings approach uses the interprocedural control flow graph of a collection of procedures where the individual control flow graphs of each procedure are merged into a single graph.

Definition 3.1.4 (Interprocedural control flow graph). Let K be a finite set of procedures. Let E 0 be the set of all intraprocedural edges (n i , n j ) of procedures in K, such that (n i , n j ) represents a direct jump from basic block n i to basic block n j . Let E 1 be the set of all interprocedural edges (n i , n j ) of procedures in K, such that (n i , n j ) represents either a procedure call in basic block n i to a procedure q (call edge), with n j the root block of q, or a procedure return from the exit block n i of a procedure q to the basic block n j in procedure p (return edge).

The interprocedural control flow graph of K is G * = (N * , E * , r main ) where the set of nodes is N * = p∈K N p , the set of edges is E * = E 0 ∪ E 1 and r main is the root block of the initial procedure of K.

Not all paths in G * are valid from an interprocedural point of view since G * ignores the specificity of procedure calls and returns, which is that a given procedure call must be eventually matched by a return to that same procedure in a well-parenthesized fashion. Definition 3.1.5 (Interprocedurally valid paths). A path is valid if it respects the fact that when a procedure returns, it returns to the most recent call site. More precisely, a path is valid if it is represented by a string in the language of the following context-free grammar:

valid → matched ( p valid | matched matched → n i | ( p matched ) p | matched matched
where ( p is representing a call to a procedure p and ) p a return from p.

We denote as IVP(n i , n j ) the set of all interprocedurally valid paths from a basic block n i to a basic block n j in G * . Definition 3.1.6 (Call string). A call string c = n 1 ...n k ∈ N * is a tuple of basic blocks such that there exists an interprocedurally valid path q ∈ IVP(r main , n) starting at the root block r main of the initial procedure main and ending in a basic block n ∈ N * which can be decomposed as q = q 0 .n 1 .r 1 .q 1 .... n k .r k .q k where q 0 is an intraprocedural path in the initial procedure starting at block r main , q 1 is an intraprocedural path in procedure p 1 starting at its root block r 1 and q k is an intraprocedural path in procedure p k starting at r k and ending in block n.

The call strings approach is still a top-down functional approach, although it avoids the propagation of data flow properties along non-interprocedurally valid paths. Each propagated property is tagged by a call string, which encodes all the procedure calls through which it has been propagated. Data flow properties associated to different call strings are kept separated.

During propagation, data flow properties are tagged by call strings which are managed as stacks and updated when propagating though a call edge or a return edge. Definition 3.1.7 (Semilattice of data flow properties with call strings). Let Γ be the set of all call strings corresponding to interprocedurally valid paths in G * . The call strings approach uses the data flow framework (L * , F * ) where L * = Γ → L is the semilattice of functions associating data flow properties to call strings. The meet operation on L * is defined as a pointwise meet operator:

∀f, g ∈ L * , ∀c ∈ Γ, (f g)(c) = f (c) g(c)
We describe the set F * of propagation functions. We define the update function, which updates call strings when procedure calls and returns are traversed during propagation. Definition 3.1.8 (Call strings update function). Let c be a call string and (n i , n j ) ∈ E * be an edge in G * . Let last(c) be the last block in the call string c and c -b be the call string c in which the basic block b has been removed. The update function is defined as:

update(c, (n i , n j )) =    c if (n i , n j ) ∈ E 0 is an intraprocedural edge c.n i if (n i , n j ) ∈ E 1 is a call edge and n i is a call block c -last(c) if (n i , n j ) ∈ E 1 is a return edge Chapter 3
Interprocedural Analysis: A State of the Art The update function appends the current block n i to the call string c when propagating c through a procedure call and removes the last block of c if we are propagating through a return edge. Thus call strings are managed as stacks, storing interprocedural events encountered during propagation. Definition 3.1.9 (Set F of propagation functions). For each edge(n i , n j ) ∈ E * of the interprocedural control flow graph, F contains a propagation function f * (n i ,n j ) : L * → L * defined as:

∀g ∈ L * , f * (n i ,n j ) (g) = λc. f (n i ,n j ) (g(c )) if ∃c , update(c , (n i , n j )) = c otherwise
The functions f * (n i ,n j ) are monotonic and distributive due to the functions f (n i ,n j ) being themselves monotonic and distributive. We compute the maximal fixed point solution of the following system of equations:

X r main = ⊥ X n j = (n i ,n j )∈E f * (n i ,n j ) (X n i )

Unbounded Call Strings and Termination

We can have unbounded call strings in the presence of unbounded recursion. In that case, the lattice L * is infinite and the classic functional approach does not converge without using any widening on call strings. We can obtain a converging analysis if we bound the length of call strings. In that case, the set Γ of call strings is finite and the lattice L * has a finite height. This solution is not sound in general and we can loose information because we ignore some possible execution paths.

However, according to theorem 5.4 in [START_REF] Sharir | Two approaches to interprocedural data flow analysis[END_REF], if the lattice L of data flow properties is finite, there is a bound M on the length of call strings for the bounded call strings approach to give a sound result. This bound is M = K(|L| | +1) 2 where K is the number of call edges and |L| is the cardinality of L.

Interprocedural Data Flow Analysis via Graph Reachability

T. Reps, S. Horwitz, and M. Sagiv proposed an algorithm in [START_REF] Reps | Precise interprocedural dataflow analysis via graph reachability[END_REF] to solve data flow problems in polynomial time over finite lattices of data flow properties and distributive propagation functions, in a top-down fashion, similarly to the functional approach of M. Sharir and A. Pnueli. This algorithm solves all data flow problems belonging to this class by converting them to a graph reachability problem. Truly live variables, copy constant propagation and possibly non-initialized variables are examples of such problems.

The considered class of data flow problems is called the IFDS class. We consider interprocedurally valid paths, just as in the call strings approach. We denote as IV P (n i , n j ) the set of interprocedurally valid paths from a node n i to a node n j in the interprocedural control flow graph of the set of procedures.

⊆ (L ∪ {0}) × (L ∪ {0}) of a propagation function f : P(L) → P(L) ∈ F is: R f = {(0, 0)} ∪ {(0, y) | y ∈ f (∅)} ∪ {(x, y) | y ∈ f ({x}) ∧ y / ∈ f (∅)}
The element 0 represents the empty set ∅. R f = {(0, 0), (0, a)}

We should remark that there is no pair (b, a) because a ∈ f ({b}) but a ∈ f (∅).

Because the IFDS problem class is specialized for finite lattices L and propagation functions on the powerset P(L) of L, a finite representation of propagation functions can be computed, and represented in a compact manner, using BDDs (Boolean Decision Diagrams) for boolean lattices.

Converting a problem of the IFDS class into a graph reachability problem Definition 3.2.3. Let IP = (G * , L, F, M, ) be an IFDS problem instance. We define an exploded interprocedural control flow graph for IP denoted by G IP = (N , E ) as follows:

N = N × (L ∪ {0}) E = {((n i , d 1 ), (n j , d 2 )) | (n i , n j ) ∈ E ∧ (d 1 , d 2 ) ∈ R M (n i ,n j ) } Chapter 3
Interprocedural Analysis: A State of the Art Each node n i ∈ N in the interprocedural control flow graph has been exploded into |L| + 1 nodes. There is a pair (n i , d) ∈ N for each node n i and each data flow property d ∈ (L ∪ {0}). There is an edge in E between two nodes (n i , d 1 ) and (n j , d 2 ) if n j is a successor of n i in the interprocedural control flow graph and if (d 1 , d 2 ) is in the relation R f , representing the propagation function M (n i , n j ) from basic block n i to basic block n j .

The IP problem corresponds to the interprocedurally valid paths reachability problem in the graph G IP from the source node (r main , 0). Let X = (X 1 , ..., X k ) be the maximal fixed point solution of an IFDS problem instance IP and X n i ⊆ L be the component of this solution associated to a basic block n i . Let d ∈ L be a data flow property in lattice L.

According to theorem 3.8 in [START_REF] Reps | Precise interprocedural dataflow analysis via graph reachability[END_REF], we have d ∈ X n i if there is an interprocedurally valid path in G IP from (r main , 0) to (n i , d). Thus we can obtain the solution of an IFDS problem instance by solving a graph reachability problem in G IP and by considering only interprocedurally valid paths.

Stack Abstractions For Interprocedural Analysis

We present in this section some approaches to interprocedural analysis which are using an abstraction of the stack.

In [START_REF] Bourdoncle | Interprocedural abstract interpretation of block structured languages with nested procedures, aliasing and recursivity[END_REF], F. Bourdoncle addresses the interprocedural abstract interpretation of a Pascallike imperative language. The author describes an analysis to partition the variables of procedures into sets of variables sharing the same location in the stack. Concrete stacks which can be encountered during a concrete execution are abstracted by abstract stacks. The call contexts of a procedure corresponding to the same abstract stack are merged. Procedures are then analyzed for each call context associated to a distinct abstract stack. We must observe that in this approach, the construction of abstract stacks is quite heavy and their definition is tedious.

Jeannet et al. [START_REF] Jeannet | Abstracting call-stacks for interprocedural verification of imperative programs[END_REF][START_REF] Sotin | Precise interprocedural analysis in the presence of pointers to the stack[END_REF] proposed a method reminiscent of the call strings approach for the relational numerical analysis of programs with recursive procedures and pointers to the stack. It is a top-down approach based on an abstraction of the stack. An implementation is available in the Interproc tool [START_REF] Jeannet | Interproc analyzer for recursive programs with numerical variables[END_REF].

Several abstractions of procedures are used. First the standard semantics is abstracted by a local semantics, in which the effect of a procedure is described only on the top activation record. In the local semantics, procedures work on local copies of memory locations.

A stack abstraction is used to obtain a reachability analysis of sets of activation records from the local semantics. The abstract stacks which are reachable at a program point in a procedure are collapsed and abstracted into sets of activation records.

We compute the set of the reachable activation records at each program point of a procedure, using a relational interprocedural abstract interpretation. Finally, we obtain an invariant which is a set of reachable activation records.

The hierarchy of abstractions used in this approach is as follows: We can make here nearly the same remark as for the previous approach. Several abstractions of the stack and activation records are performed. Thus we can question the necessity of such stack abstractions and the possible alternatives for interprocedural abstract interpretation especially regarding the complexity of their definition and their construction.

A stack abstraction is also performed in [START_REF] Rival | The trace partitioning abstract domain[END_REF] for trace partitioning. Interprocedural traces are abstracted here by functions Stack×Loc → P(S) from pairs (k, l) ∈ Stack×Loc made of a stack and a control state, to a set S of memory states. Thus we obtain an analysis which is sensitive to the calling context, at the expense of keeping potentially large abstractions of the stack.

The call strings approach, which is separating data flow properties according to the encountered call contexts, is an early example of stack abstraction since call strings are updated with representations of the procedure calls and procedure returns encountered during propagation.

Statement-level Summaries

An approach based on statement-level summaries implemented in the PIPS tool [START_REF] Ancourt | A modular static analysis approach to affine loop invariants detection[END_REF][START_REF] Irigoin | Semantical interprocedural parallelization: An overview of the PIPS project[END_REF] was proposed to discover linear invariants in a collection of procedures by abstract interpretation. Statements in procedures are abstracted by affine transformers [START_REF] Maisonneuve | Computing invariants with transformers: experimental scalability and accuracy[END_REF] which are input-output relations represented by convex polyhedra. The summary of a whole procedure is obtained from the composition of statement transformers, in a bottom-up fashion.

This analysis is divided into two phases, a transformer computation phase and an invariant generation phase.

Each statement is first abstracted by a convex polyhedron representing a linear relation between the state of the variables before the statement and their state after the execution of that statement. Transformers for control structures are computed from the transformers of individual statements. An algorithm is given to compute an abstraction of the transformer of a loop from the transformer of its body, which is termed the Affine Derivative Closure algorithm.

Invariants are obtained by forward propagation of the procedure precondition using the transformers computed in the previous phase.

However, precision can be lost during the composition of individual statement transformers. For each transformer, the number of variables can be doubled in the worst-case to express the initial states of numerical variables. The execution time can increase exponentially during the computation of statement transformers due to the complexity of convex polyhedra operations.

Chapter 3

Interprocedural Analysis: A State of the Art Statement-level transformers are also used in [START_REF] Yorsh | Generating precise and concise procedure summaries[END_REF], to solve interprocedural data flow problems belonging to the IFDS class (see Definition 3.2.1). Procedure summaries are derived from the composition of statement-level transformers. Transformers of loop statements are constructed by iterated composition of the loop body transformer, until a fixed point is reached. Convergence is guaranteed because the IFDS problem class is concerned only by finite lattices.

Aggregate domains, abstract domains which can be expressed as aggregates of simpler domains, allow transformers to be broken into micro-transformers, each micro-transformer operating on a sub-domain. Each micro-transformer can separate cases corresponding to distinct classes of values in a sub-domain, each having a precondition that defines a distinct class of values and a postcondition describing how values are transformed. The aim is to have micro-transformers consisting of cases defined on values behaving uniformly with simpler postconditions.

Procedure Summaries Using Generic Assertions

The approach proposed in [START_REF] Gulwani | Computing procedure summaries for interprocedural analysis[END_REF] is a bottom-up approach computing summaries of procedures by backward propagation of generic assertions. A generic assertion is an assertion which must be instantiated by symbols of an underlying abstraction.

For example, a generic assertion in the theory of linear arithmetic is αx+βy = γ where α, β and γ are unknown variables. The assertion which has to hold after a procedure call must be given manually. It is matched using a unification algorithm to the generic assertion computed for the called procedure.

Example 3.5.1. We assume that the generic assertion summarizing a procedure p is αx + βy = γ. We want to check that the assertion y = 2x + 1 holds after a call to p. We match y = 2x + 1 with the generic assertion αx + βy = γ and we obtain the substitution α → -2, β → 1 and γ → 1. This substitution can be used to compute the summary of the calling procedure, in a bottom-up fashion.

Procedure summaries are obtained by computing the weakest precondition of each generic assertion at each point of a procedure. A fixed point computation is performed to handle loops. The authors describe a generic assertion simplification technique because a naive weakest precondition computation can be exponential in the number of operations performed.

Relational Interprocedural Analyses

Modular Static Analysis

Cousot et al. [START_REF] Cousot | Compositional separate modular static analysis of programs by abstract interpretation[END_REF][START_REF] Cousot | Modular static program analysis[END_REF] describes the symbolic relational separate analysis for abstract interpretation, which uses relational abstract domains, relational semantics and symbolic names to represent initial values of parameters modified by a procedure. When used with the polyhedra abstract domain, the approach computes procedure summaries which are input-output relations represented by a single convex polyhedron, with no ability to capture disjunctive behaviors in procedures. Recursive procedures are supported, although the technique is quite classical and was already presented earlier in [START_REF] Cousot | Static determination of dynamic properties of recursive procedures[END_REF][START_REF] Cousot | Relational abstract interpretation of higher order functional programs[END_REF][START_REF] Halbwachs | Détermination automatique de relations linéaires vérifiées par les variables d'un programme[END_REF].

Relational Interprocedural Analyses

Relational Abstractions of Functions

A relational abstraction of sets of functions for shape analysis is proposed in [START_REF] Jeannet | A relational abstraction for functions[END_REF]. It considers functions of signature D 1 → D 2 , provided that there exists abstractions A 1 of P(D 1 ) and A 2 of P(D 2 ) and that A 1 has a finite cardinality. This abstraction is relational since it is able to express relations between elements mapped by a set of functions. However the abstraction A 1 is required to be of finite cardinality, thus excluding usual numerical abstract domains such as convex polyhedra.

Interprocedural Analyses based on Linear Algebra

Müller-Olm et al. [START_REF] Müller-Olm | Interprocedural analysis (almost) for free[END_REF] proposed an interprocedural bottom-up analysis discovering all Herbrand equalities between program variables at each program point in polynomial time. It considers abstracted programs with only affine assignments, ignoring conditions on branches, with other assignments handled soundly as non-deterministic assignments. An algorithm for precise interprocedural value numbering is derived from this approach.

An extension was proposed in [START_REF] Flexeder | Fast interprocedural linear two-variable equalities[END_REF] to obtain an interprocedural analysis to discover linear two-variable equalities. It has a worst-case complexity of O(nk 4 ) where n is the program size and k is the number of program variables. It infers all valid equalities between program variables of the form x i = c or x i = x j + c where c ∈ Z. No widening operator is necessary.

Each procedure p is represented by a control flow graph G p with control locations as nodes and edges labeled with program statements. Let X be the set of all program variables. A finite satisfiable set of equalities E can be represented by a weighted directed graph, where the set of nodes is X ∪ {0} and there is an edge from x i to x j with weight b if there the equality x i = x j + b is valid. The graph is assumed to be symmetric and transitive. An equality x i = c with c ∈ Z is represented by an edge from x i to 0 with weight c.

For every maximal connected component C of the graph, we choose a reference node, which is either 0 or the variable x i with the least index i. For every other variable x j in C, we only record the equality x j = b or x j = x i + b. The conjunction of all those equalities is equivalent to E. A conjunction of such properties is said to be normalized. A normalized conjunction consists of at most k equalities and can be represented by an array of size k.

The length of every strictly increasing chain f alse E 1 ... E n is bounded by k + 1, because in every pair E i E i+1 , E i+1 has strictly more connected components than E i and the number of connected components in a graph of k + 1 nodes is bounded by k + 1.

Summaries of procedures are obtained by computing weakest preconditions of generic postconditions. For example, consider the procedure p below.

void p() { x1 = x1 + 1; x2 = x2 -1; } Interprocedural Analysis: A State of the Art
The procedure p increments the global variable x1 and decrements the global variable x2. We are interested in the postconditions at the end of the procedure which are of the form:

x 1 = a ∧ x 2 = b ∧ x 2 = x 1 + c with a, b, c ∈ Z. The postcondition x 1 = a ∧ x 2 = b ∧ x 2 = x 1 + c,
where a, b, c are left as placeholder variables, is called a generic postcondition. The summary of procedure p is obtained by computing the weakest precondition of the generic postcondition:

Precondition x 1 = a -1 ∧ x 2 = b + 1 ∧ x 2 = x 1 + c + 2 Postcondition x 1 = a ∧ x 2 = b ∧ x 2 = x 1 + c
This approach is not able to express disjunctions in the procedure summary. It is extended to discover linear two-variable equalities, which are equalities of the form x i = c or x i = ax j + b. Such a set of linear equalities can be put into a normal form where each variable appears in only one equality. Therefore, when in normal form, a set E of linear equalities has at most k equalities. The summary of a procedure is obtained by computing weakest preconditions of linear generic postconditions of the form a 1 x i = a 2 or a 1 x i = a 2 x j + a 3 .

Dual Interprocedural Analysis using Linear Arithmetic

Popeea et al. [START_REF] Popeea | Inferring disjunctive postconditions[END_REF][START_REF] Popeea | Dual analysis for proving safety and finding bugs[END_REF][START_REF] Popeea | Dual analysis for proving safety and finding bugs[END_REF] presented an analysis to both prove user-supplied safety properties and to find bugs by deriving a condition ok leading to success and a condition err leading to failure for each procedure of a program. The summary of a procedure is a pair (ok, err) of these two conditions, with ok and err being formulas in the first-order theory of linear arithmetic.

The conditions ok and err of the procedure summary are inferred in a bottom-up fashion, from callees to callers. The analysis is done in two steps:

1. A constraint abstraction of the procedure body is generated according to Hoare-style rules for success and failure outcomes. 2. A fixpoint computation is used to derive closed-form formulas for both ok and err. Disjunctive numerical properties can be represented in the ok and err formulas, with linear equalities and inequalities. Simplification of formulas and checking for satisfiability is handled by a complete decision procedure for linear arithmetic provided by the Omega Test [START_REF] Kelly | The Omega calculator and library, version 1.1.0[END_REF]. The Omega Test is known to have a doubly-exponential worst-case complexity. This approach is implemented in the DUALYZER tool.

Part II Relational Summaries for Interprocedural Analysis

Chapter 4

Relational Abstract Interpretation

Relational abstract interpretation is concerned by the automatic discovery of relations between the variables of a program at each program point. Linear Relation Analysis (LRA) proposed in [START_REF] Cousot | Automatic discovery of linear restraints among variables of a program[END_REF][START_REF] Halbwachs | Détermination automatique de relations linéaires vérifiées par les variables d'un programme[END_REF][START_REF] Irigoin | Semantical interprocedural parallelization: An overview of the PIPS project[END_REF] is the archetypal numerical relational analysis. Although we are particularly interested in its application to Linear Relation Analysis, relational abstract interpretation is not specific to numerical analyses, it also encompasses any analysis inferring relations among states of a program, such as for example in shape analysis, where relations may be inferred between memory elements or parts of data structures.

By inferring abstract relations between states in a program, particularly between the initial values of variables at the entry of a procedure and their values at exit, relational abstract interpretation can serve as a foundation to compute relational summaries of procedures.

We present in this chapter a formalization of relational abstract interpretation that we did not find elsewhere. We start by giving a general characterization of relational abstract domains, as abstractions of binary relations over sets of program states, since they are the key ingredient to represent relations between states. Then, we take a particular attention to procedure preconditions and we show that preconditions must be treated carefully in order to obtain precise relational procedure summaries.

Relations on States and the Transitive Closure

We introduce some definitions and notations on states and relations as a prelude to our presentation of relational abstract interpretation.

States and Relations

Let S be a set of states. We denote as ρ ⊆ S × S a relation over states. We denote as R = P(S × S) the set of binary relations over S.

A relation ρ over S is a set of pairs (s 1 , s 2 ) of states s 1 , s 2 ∈ S, where s 1 is termed the source component of the pair and s 2 is termed the target component of the pair. We define classically the source projection src : R → S and the target projection tgt : R → S of binary relations as:

∀ρ ∈ R, src(ρ) = {s 1 ∈ S | ∃s 2 ∈ S, (s 1 , s 2 ) ∈ ρ} ∀ρ ∈ R, tgt(ρ) = {s 2 ∈ S | ∃s 1 ∈ S, (s 1 , s 2 ) ∈ ρ} If U ⊆ S is a subset of S, then we denote the identity relation over U as Id U = {(s, s) | s ∈ U }.
Definition 4.1.1 (Composition of binary relations). Let ρ 1 , ρ 2 ∈ R be binary relations over a set S. The composition ρ 1 • ρ 2 of ρ 1 , ρ 2 is defined as:

∀ρ 1 , ρ 2 ∈ R, ρ 1 • ρ 2 = {(s 1 , s 3 ) | ∃s 2 ∈ S, (s 1 , s 2 ) ∈ ρ 1 ∧ (s 2 , s 3 ) ∈ ρ 2 } Transitive Closure Definition 4.1.2 (Transitive closure). Let ρ ⊆ S × S is a binary relation over S. The transitive closure ρ of ρ is defined as: ρ = k≥0 ρ k
If we consider the transition relation ρ ⊆ S × S of a transition system, the transitive closure ρ relates states which are reachable from one another in a finite number of computation steps of the system described by the transition relation. The system can be, for example, a program or a procedure. The image tgt(ρ (I)) of a set I of initial states by the transitive closure ρ is the set of reachable states of the transition system under consideration.

As an endpoint to these introductory matters on relations, we point the interested reader to some classical references on the theory of binary relations, such as Tarski's classical revival paper [START_REF] Tarski | On the calculus of relations[END_REF] on the calculus of relations and [START_REF] Pratt | Origins of the calculus of binary relations[END_REF].

Forward and Backward Relational Semantic Equations

The transitive closure ρ of ρ can be expressed as the least solution of a forward fixpoint equation and equally as the least solution of a backward fixpoint equation:

ρ = µr. Id S ∪(r • ρ) (forward equation) ρ = µr. Id S ∪(ρ • r) (backward equation)

Trace Partitioning

Following the classical trace partitioning technique, we assume that the set S of states is finitely partitioned according to a partition δ = {S 1 , S 2 , ..., S n } as follows:

∀S i , S j ∈ δ, i = j ⇒ S i ∩ S j = ∅ S i ∈δ S i = S
We can also denote S as the disjoint sum S = S 1 ⊕ S 2 ⊕ ... ⊕ S n of the members of the partition δ,

Relations on States and the Transitive Closure

Example 4.1.1. Trace partitioning can be done according to the control locations of a program. We assume that L = {l 1 , l 2 , ..., l n } is a finite set of control locations, V is a set of values and the set S of program states is the cartesian product S = L × V n . We construct classically the partition δ L of S according to control locations in L as follows:

δ L = n i=1 {(l i , V ) ∈ L | V ∈ V n }
A partitioning can also be defined in a more semantic fashion and can express state properties, like preconditions.

∀S i , S j ∈ δ, ρ(S i , S j ) = ρ ∩ (S i × S j )
Property 4.1.1. The restriction ρ (S i , S j ) of the transitive closure ρ to S i , S j ∈ δ can be expressed as the least fixpoint of the following system of forward fixpoint equations:

∀i = j, ρ (S i , S j ) = n k=1 ρ (S i , S k ) • ρ(S k , S j ) ρ (S i , S i ) = Id S i ∪ n k=1 ρ (S i , S k ) • ρ(S k , S i )
Intuitively, for any states s i ∈ S i and s j ∈ S j , the membership (s i , s j ) ∈ ρ (S i , S j ) of the pair (s i , s j ) in ρ (S i , S j ) means that s j can be reached from s i by iterated composition of the binary relation ρ with itself, and since S i and S j are disjoint, the binary relation ρ must be applied at least once. If we consider ρ as the relation of a transition system on S, this means that the state s j ∈ S j is reachable from the state s i ∈ S i in a finite, but non-zero, number of computation steps. Additionally, if (s i , s j ) ∈ ρ (S i , S i ), the state s j is reachable from s i in zero computation steps if s i = s j . As illustrated in Figure 4.1, we can split the path from a state s i ∈ S i to a state s j ∈ S j into a finite path from s i to a state s k ∈ S k with S k ∈ δ, denoted as (s i , s k ) ∈ ρ (S i , S k ), and an atomic computation step from s k to s j , denoted as (s k , s j ) ∈ ρ(S k , S j ). Then, the transitive closure ρ (S i , S j ) is the union of all such splittings for each S k ∈ δ.

s i s k s j ρ (S i , S k ) ρ(S k , S j ) S i S k S j

Concrete Relational Semantics

We denote as (S, ρ, I, E) the transition system describing a procedure p where S is a set of states, ρ ⊆ S × S is the transition relation of p, I ⊆ S is the set of initial states and E ⊆ S is the set of exit states.

Concrete Relational Summaries

Definition 4.2.1 (Concrete Relational Summary). The concrete relational summary of a procedure p is σ p = ρ (I, E).

The concrete summary σ p of a procedure p is the transitive closure of the transition relation ρ restricted to the set I of initial states and to the set E of exit states. It is the set of pairs (s I , s E ) made of an initial state s I ∈ I and of an exit state s E ∈ E reachable from s I in a finite number of computation steps in the procedure p.

For the forward computation of a summary σ p we are interested in the computation of ρ (I, S j ) for each S j ∈ δ by instantiating the fixpoint characterization of ρ (S i , S j ) given in Property 4.1.1 using the following equations:

ρ (I, S j ) = n k=1 ρ (I, S k ) • (S k , S j ) ∪ Id I if S j = I ∅ otherwise

Concrete Semantics of Procedure Calls

The concrete summary of a procedure p can be used to express the set of states reachable after a call to p given the states reachable immediately before the call. We can use the summary of a called procedure to obtain its effect in a caller.

We make first some assumptions on the programs that we are considering in this presentation for the sake of clarity, and we will consider thereafter that the necessary transformations are available in practice.

We assume that all procedure parameters are given and that there are no parameters with default values, neither partially-applied procedures.

We consider that all procedure parameters in a program are passed by reference, we are not concerned with pointer manipulation in this presentation. We entrust existing pointer analyses to detect aliasing problems and to provide us an abstraction of numerical procedures consistent with our assumptions, on top of which our analysis should be built in practice.

Instead of an explicit program transformation prior to our analysis, our approach could also be used on top of another analysis providing us only a suitable view of procedures, in which we would only work with abstract numerical variables and expressions generated by a memory abstract domain, such as in [START_REF] Miné | Field-sensitive value analysis of embedded C programs with union types and pointer arithmetics[END_REF].

We assume that global variables are dealt with as additional procedure parameters. All variables are assumed to be parameters, since local variables don't raise any problem from the point of view of relational collecting semantics.

Let p be a procedure with a set S of states and let T be the set of states of a program calling p. We denote as π : P(S × S) → P(T × T ) the parameter passing mechanism for the summary of p, which consists in renaming formal parameters into actual ones.

Concrete Relational Semantics

Definition 4.2.2. Let T i ⊆ T be the set of states reachable just before the call to p and let T j ⊆ T be the set of states reachable just after the call to p. The effect of the call to p is described by the elementary relation ρ(T i , T j ) = π(ρ p ).

From State to Relational Collecting Semantics

We are particularly interested in the relational analysis of numerical procedures and we describe how a relational collecting semantics can be obtained from the usual collecting semantics of a procedure.

States of Numerical Procedures

A state of a numerical procedure with n variables is a pair ( , V ) ∈ Loc × N n where ∈ Loc is a control location such as a line, a statement or a block in a control-flow graph, and

V = (v 1 , ..., v n ) ∈ N n is a vector of numerical values in N .

Partitioning

Control locations ∈ Loc provide a natural partitioning of sets of states. We denote as

S = {( , V ) | V ∈ N n } the set of states at a control location .
The set of initial states of a procedure at an entry control location I is denoted as S I and can be further restricted by a precondition A I ∈ N n such as:

I = {( I , V ) | V ∈ A I }

State Collecting Semantics

The usual collecting semantics defines the set A of reachable variable valuations at a control location in a procedure with A = {V | ( , V ) is a reachable state from I} as the least fixpoint of a system of fixpoint equations:

A = F ({A | ∈ Loc}) ∪ A I if = I ∅ otherwise
where the transfer function F expresses how the states in S depends on the states at other control points. The sets A of reachable states at each control location are termed the collecting semantics of the procedure.

Relational Collecting Semantics

Collecting semantics on states can be extended to relational semantics as follows: for each variable v i , a new variable v 0 i is introduced to record the initial value of the variable v i . The new set of states is S R = Loc × N 2n and the new set of initial states is defined as follows:

A R I = {(v 0 1 , ..., v 0 n , v 1 , ..., v n ) | (v 0 1 , ..., v 0 n ) ∈ A I ∧ v i = v 0 i , i ∈ {1, ..., n}} I R = {(l I , V ) | V ∈ A R I }
The relational collecting semantics of the procedure is equivalent to the usual state collecting semantics of the procedure initialized with the assignments v 0 i = v i for each i ∈ {1, ..., n}.

The relational collecting semantics A R at a control location ∈ Loc are defined as:

A R = F R ({A R | ∈ Loc}) ∪ A R I if = I ∅ otherwise
The introduction of v 0 i variables to record initial values of variables is the only change made with respect to the usual collecting semantics. Extended states are propagated and transformed in the classical way by the transfer functions F R representing the effect of statements at each control location ∈ Loc. We assume that the propagation functions F R do not change the values of the v 0 i variables. Let E ∈ Loc be the set of exit control locations of a numerical procedure p. The concrete summary σ p of the numerical procedure p can be defined as follows:

σ p = ∈E A R
If we consider the presence of local variables, they should be eliminated from this expression by existential quantification.

Thus the relational collecting semantics of a numerical procedure can be obtained in a rather simple fashion from the usual state collecting semantics.

A very simple example

We give thereafter a very simple example of relational concrete summary. We consider the example program in Figure 4.2, which implements the classical Euclidean division, by the method of successive subtractions, as described originally in [START_REF]Euclid of Alexandria[END_REF].

void div(int a, int b, int * q, int * r) { assume(a >= 0 && b >= 1); 1: *q = 0; *r = a; 2: while 3: The system of concrete fixpoint equations representing the div procedure is given on the right-hand side of Figure 4.2. The set of reachable variable valuations at a control location i is given by the set A i .

(*r >= b) { *r = *r-b; 4: *q = *q + 1; 5: } 6:} A 1 = {(a 0 , b 0 , q 0 , r 0 , a, b, q, r) | a 0 ≥ 0 ∧ b 0 ≥ 1 ∧ a = a 0 ∧ b = b 0 ∧ q = q 0 ∧ r = r 0 } A 2 = A 1 [q := 0][r := a] A 3 = A 2 ∪ A 5 A 4 = A 3 ∩ (r ≥ b) A 5 = A 4 [r := r -b][q := q + 1] A 6 = A 3 ∩ (r ≤ b -1)
The concrete relational summary of the div procedure is given by the least fixpoint solution for A 6 , at the unique exit point of the procedure:

A 6 = (a = a 0 ∧ b = b 0 ∧ a = bq + r ∧ q ≥ 0 ∧ r ≤ b -1 ∧ r ≥ 0 ∧ a 0 ≥ 0 ∧ b 0 ≥ 1)
It describes the effect of the div procedure on its parameters, by relating their final value at the exit point of the procedure back to their initial value at the entry of the div procedure. Relations between final values of parameters are recorded as well.

We should notice that the concrete summary of the div procedure contains a nonlinear relation, a = bq + r, which is the well-known property of Euclidean division, and thus will not be obtainable by Linear Relation Analysis, as non-linear relations can not be represented by convex polyhedra.

Relational Abstract Interpretation 4.3.1 General Framework Relational Abstract Domain

A relational abstract domain is an abstract domain providing an abstraction of sets of binary relations over program states.

Definition 4.3.1 (Relational abstract domain). A relational abstract domain is a com- plete lattice (R , , ⊥, , , ) related to R by a Galois connection (α R , γ R ).
Example 4.3.1. We consider the set {x, y, z} of numerical variables and the set S = Z 3 of variables valuations. We give some abstract relations over S expressed in the convex polyhedra abstract domain:

r 1 = (x = x 0 + 1 ∧ y = y 0 ∧ z 0 ≥ z ∧ y ≥ 23 ∧ x ≥ 1) r 2 = (y = 2y 0 + 1 ∧ x 0 ≤ x ≤ x 0 + 2y ∧ 1 ≤ y ≤ z)
It is well-known that we can express abstract relations between numerical states in the convex polyhedra abstract domain by introducing a doubled vocabulary of variables X 0 , X where variables in X 0 represent the source state and variables in X represent the target state. In example 4.3.1, we duplicated variables x, y, z and introduced variables x 0 , y 0 , z 0 to denote the initial value of variables x, y, z.

For U ⊆ S, we denote as Id (U ) the abstract relation α R (Id U ) which is the abstraction in R of the identity relation over U . Definition 4.3.2 (Composition of abstract relations). The composition r 1 • r 2 of two abstract relations r 1 , r 2 ∈ R is defined as:

r 1 • r 2 = α R (γ R (r 1 ) • γ R (r 2 ))
A relational abstract domain R induces two abstract domains S → and S ← on the set S of states as follows:

∀U ⊆ S, α S→ (U ) = α R (U × S) α S← (U ) = α R (S × U )
We should note that both abstract domains S → and S ← are included in R . Abstract domains S → and S ← represent a set U of states as an abstract relation where U can be either abstracted as the source or as the target of the abstract relation respectively. Definition 4.3.3 (Abstract projections). The abstract source projection src : R → S → of abstract relations in a relational abstract domain R is defined as:

src (r ) = α S→ (src(γ R (r )))
Similarly, we define the abstract target projection dst : R → S ← as follows:

tgt (r ) = α S← (tgt(γ R (r )))

Relational Abstract Analysis

Let ρ ⊆ S × S be a transition relation over a set S of states. Let ρ ∈ R be an upper bound of its abstraction in the relational abstract domain R with α R (ρ) ρ . In order to ensure convergence, we assume that the relational abstract domain R provides both a widening operator ∇ : R × R → R and a narrowing operator : R × R → R .

An upper approximation of the transitive closure ρ of an abstract relation ρ can be obtained by computing the limit r ∇ of an increasing sequence (r n ) n≥0 defined as:

r 0 = ⊥ r n+1 = r n ∇(r n • ρ)
and by computing the limit r ∇ of a decreasing sequence (r n ) n≥0 defined as:

r 0 = r ∇ r n+1 = r n (r n • ρ)
The limit r ∇ is a sound approximation of the transitive closure ρ of the concrete transition relation ρ where ρ ⊆ γ R (r ∇ ).

Abstract Partition

A relational abstract domain R induces two abstract domains S ← and S → both providing abstractions of the set S of states. We can define an abstract partition of the abstract domain S ↔ for each direction ↔∈ {←, →}. Definition 4.3.4 (Abstract partition). Let S ↔ be an abstract domain obtained from a relational abstract domain

R . A finite abstract partition δ ⊆ S ↔ of S ↔ is a finite set δ = {S 1 , ..., S n }, such that {S i = γ S↔ (S i ) | S i ∈ δ } is a partition of S.
It is interesting to consider an abstract partition δ = {S 1 , ..., S n } of S ↔ if the behavior of a transition system can be split into several distinct behaviors expressed by abstract elements S 1 , ..., S n .

More generally, for any subset U ⊆ S of states, we can define an abstract partition

δ of U ← = α S↔ (U ) as a finite set δ = {U 1 , ..., U n } where {U i = γ S↔ (U i ) | U i ∈ δ } is a partition of U .
This is especially useful when we consider a precondition A ⊆ S and we are interested in an abstract partition relative to the precondition A, which is an abstract partition of α S↔ (A).

Partitioned Relational Analysis

Let ρ ⊆ S × S be a transition relation over S. Let δ = {S 1 , ..., S n } be an abstract partition of S = α(S).

For each S i , S j ∈ δ , we assume that we have an upper bound ρ (S i , S j ) ∈ R of the abstraction α R (ρ(S i , S j )) of ρ(S i , S j ) with α R (ρ(S i , S j )) ρ (S i , S j ).

An upper approximation of the vector {ρ (S i , S j ) | S i , S j ∈ δ } can be obtained as the limit of the increasing-decreasing sequences computed from the following system of fixpoint equations:

∀i ∈ {1, ..., n}, ∀i = j, ρ (S i , S j ) = n k=1 ρ (S i , S k ) • ρ (S k , S j ) ρ (S i , S i ) = Id S i n k=1 ρ (S i , S k ) • ρ (S k , S i )

Abstract Summary of a Procedure

Let p be a procedure represented by a transition system (S, ρ, I, E). We denote as I = α(I) the abstraction of initial states and as E = α(E) the abstraction of exit states. Definition 4.3.5 (Abstract summary). The abstract summary of a procedure p described by a transition system (S, ρ, I, E) is σ p = ρ (I , E ).

The abstract effect of a call to a procedure p with an abstract parameter passing mechanism π : R → R , located between T i and T j is ρ (T i , T j ) = π (σ p ).

Building Summaries Using LRA

The convex polyhedra abstract domain is a relational abstract domain abstracting a set of numerical vectors by its convex hull which is its least convex superset. A detailed presentation of the convex polyhedra abstract domain is given in Chapter 2.

Classical abstract domain operations are available, such as intersection (P 1 P 2 ), convex hull (P 1 P 2 ), effect of variable assignment (P [x := expr]), widening (P 1 ∇P 2 ), test for inclusion (P 1 P 2 ) and emptiness (P = ∅). Instead of using a narrowing operator to ensure the convergence of the decreasing sequence, only a limited number of iterations of the decreasing sequence is computed. It is sound to do so since all terms of the decreasing sequence are post-fixpoints of the abstract transfer function. A projection operation (∃X, P ) also termed existential quantification is provided.

As shown in Example 4.3.1, convex polyhedra can represent abstract input-output relations. We introduce additional variables to denote initial values and the source of the relation. We denote as X 0 the finite set of variables representing initial values of variables. We denote as P (X 0 , X) the convex polyhedron involving variables in X 0 denoting initial values and variables in X denoting current values.

The source and the target projection of an abstract relation r represented by a convex polyhedron can be defined straightforwardly using the projection operator. Definition 4.3.6. The abstract source projection src : N n → N n of abstract relations represented by convex polyhedra is defined as:

src (P (X 0 , X)) = ∃X, P (X 0 , X)
Similarly, we define the abstract target projection tgt : N n → N n as follows:

tgt (P (X 0 , X)) = ∃X 0 , P (X 0 , X) Example 4.3.2.
The source and target projections of the abstract relations defined in Example 4.3.1 are:

r 1 = (x = x 0 + 1 ∧ y = y 0 ∧ z 0 ≥ z ∧ y ≥ 23 ∧ x ≥ 1) src (r 1 ) = (x 0 ≥ 0 ∧ y 0 ≥ 23) tgt (r 1 ) = (x ≥ 1 ∧ y ≥ 23) r 2 = (y = 2y 0 + 1 ∧ x 0 ≤ x ≤ x 0 + 2y ∧ 1 ≤ y ≤ z) src (r 2 ) = (y 0 ≥ 0) tgt (r 2 ) = (y ≥ 1 ∧ z ≥ y)
The composition of abstract relations expressed as convex polyhedra can be defined naturally using classical operators. Definition 4.3.7 (Composition of convex polyhedra). Let r 1 and r 2 be abstract relations represented by convex polyhedra P 1 (X 0 , X 1 ) and P 2 (X 1 , X 2 ) over finite sets of variables X 0 , X 1 , X 2 , X 3 . The abstract composition of r 1 and r 2 is defined as:

r 1 • r 2 = ∃X 1 , (P 1 (X 0 , X 1 ) P 2 (X 1 , X 2 ))
We can compute relational procedure summaries using Linear Relation Analysis where procedure summaries are input-output relations represented by convex polyhedra.

We introduce X 0 variables to denote initial values of procedure parameters. For the sake of clarity, we duplicate all procedure parameters for the time being, at least in principle. In practice, we do not have to duplicate a procedure parameter if it is a pure input parameter or a pure output parameter. Following relational collecting semantics, we introduce equalities at procedure entry between X 0 variables denoting initial values and X variables denoting current values of procedure parameters.

The relational summary of a procedure is given by the convex polyhedra obtained at the procedure exit.

Example

We compute an abstract relational summary of the div procedure defined in our Euclidean division example. We give the system of abstract fixpoint equations over the convex polyhedra abstract domain associated to the div procedure.

Preconditions

void div(int a, int b, int * q, int * r) { assume(a >= 0 && b >= 1); 1: *q = 0; *r = a; 2: while 3:

(*r >= b) { 4:

*r = *r-b; *q = *q + 1; 5: } 6:} A standard Linear Relation Analysis, where the widening operator is applied on P 3 during the increasing sequence and the decreasing sequence is limited to 2 iterations, gives the following fixpoint solution for the div procedure:

P 1 = (a 0 ≥ 0 ∧ b 0 ≥ 1 ∧ a = a 0 ∧b = b 0 ∧ q = q 0 ∧ r = r 0 ) P 2 = P 1 [q := 0][r := a] P 3 = P 2 P 5 P 4 = P 3 (r ≥ b) P 5 = P 4 [r := r -b][q := q + 1] P 6 = P 3 (r ≤ b -1)
P 1 = (a 0 ≥ 0 ∧ b 0 ≥ 1 ∧ a = a 0 ∧ b = b 0 ∧ q = q 0 ∧ r = r 0 ) P 2 = (a 0 ≥ 0 ∧ b 0 ≥ 1 ∧ a = a 0 ∧ b = b 0 ∧ q = 0 ∧ r = a) P 3 = (a = a 0 ∧ b = b 0 ∧ r ≥ 0 ∧ q ≥ 0 ∧ b ≥ 1 ∧ a ≥ q + r) P 4 = (a = a 0 ∧ b = b 0 ∧ r ≥ b ∧ q ≥ 0 ∧ b ≥ 1 ∧ a ≥ q + r) P 5 = (a = a 0 ∧ b = b 0 ∧ r ≥ 0 ∧ q ≥ 1 ∧ b ≥ 1 ∧ a + 1 ≥ b + q + r) P 6 = (a = a 0 ∧ b = b 0 ∧ r ≥ 0 ∧ q ≥ 0 ∧ b ≥ r + 1 ∧ a ≥ q + r)
The program point 6 is the unique exit point of the div procedure. In our system of abstract fixpoint equations, P 6 is the convex polyhedron associated to the exit point of the div procedure. Although the non-linear property a = bq + r of Euclidean division can not be expressed in the convex polyhedra abstract domain, we still obtain a rather weak summary for the div procedure given by P 6 . We shall also remark in P 6 that the precondition a 0 ≥ 0 has been lost. This suggests that preconditions should be considered more carefully.

Preconditions

For closed programs, the initial state is generally not relevant, since normally, variables are explicitly assigned an initial value before being used. Even global variables can be considered to be assigned by a global initialization procedure executed right before the main procedure. Global variables may also have a default initial value according to their type in programming languages such as C. From the point of view of a static analysis tool, we can consider that even if these default values are implicit from the programmer side, they can still be seen as explicit variable assignments.

When looking at procedures during a concrete program execution, the initial values of formal parameters comes from the values passed as actual parameters by a calling procedure. Conversely, when considering procedures individually in themselves, the initial values of parameters are left undetermined and parameters can possibly take initially any value in their semantic domain with respect to their type.

The correct behavior of a procedure often depends on a precondition, which is a property constraining the initial values that parameters are allowed to take. We denote as I p the concrete precondition of a procedure p. We term as global precondition the abstraction I p of the set of legal initial states of a procedure p where I p = α S→ (I p ).

We took into account the global precondition a 0 ≥ 0 ∧ b ≥ 1 of the div procedure in our Euclidean division example. Such a global precondition can be user-supplied, as a manually given annotation in the program source, or discovered by another analysis from the calling context, or in a weaker form from the types of parameters. The global precondition can also be simply representing the total absence of information about initial values of parameters.

Widening Under a Precondition

In a relational analysis, a precondition is an obvious invariant, since it is a property on initial values of procedure parameters and a procedure can not change its initial state. Thus any concrete summary σ p of a procedure p and any concrete relation ρ (I p , S i ) has its source within I p . This is less obvious for an abstract analysis because of the use of widening.

It may happen that the result r ∇ of a relational abstract analysis does not satisfy the invariant given by a precondition, when γ(r ∇ ) is not included in I p × S due to classical widening operators being defined independently of any procedure precondition. This is what happened in our Euclidean division example during the computation of an abstract relational summary of the div procedure.

As a consequence, it is both sound and interesting to use a limited widening operator, taking into account the procedure precondition during the increasing sequence of the relational abstract analysis to compute r ∇ . Definition 4.4.1 (Widening limited by precondition). The widening operator ∇ I p : R → R limited by an abstract precondition I p ∈ R is defined as:

∀r 1 , r 2 ∈ R , r 1 ∇ I p r 2 = (r 1 ∇r 2 ) I p
Example 4.4.1. In our Euclidean division example, when computing a relational abstract summary of the div procedure, the classical widening operator was applied on P 3 with P 3 = P 3 ∇(P 2 P 5 ). Instead, we limit the widening on P 3 by the global precondition of the div procedure:

P 3 = (P 3 ∇(P 2 P 5 )) (a 0 ≥ 0 ∧ b 0 ≥ 1)
We compute a new relational summary of the div procedure according to the following system of abstract fixpoint equations:

I = (a 0 ≥ 0 ∧ b 0 ≥ 1) P 1 = I (a = a 0 ∧ b = b 0 ∧ q = q 0 ∧ r = r 0 ) P 2 = P 1 [q := 0][r := a] P 3 = (P 3 ∇(P 2 P 5 )) I P 4 = P 3 (r ≥ b) P 5 = P 4 [r := r -b][q := q + 1] P 6 = P 3 (r ≤ b -1)
Using Linear Relation Analysis, we obtain the following abstract values for I , P 1 , P 2 , P 3 , P 4 , P 5 , P 6 :

I = (a 0 ≥ 0 ∧ b 0 ≥ 1) P 1 = (a = a 0 ∧ b = b 0 ∧ q = q 0 ∧ r = r 0 ∧ b ≥ 1 ∧ a ≥ 0) P 2 = (r = a ∧ a = a 0 ∧ b = b 0 ∧ q = 0 ∧ b ≥ 1 ∧ a ≥ 0) P 3 = (a = a 0 ∧ b = b 0 ∧ r ≥ 0 ∧ q ≥ 0 ∧ b ≥ 1 ∧ a ≥ q + r) P 4 = (a = a 0 ∧ b = b 0 ∧ r ≥ b ∧ q ≥ 0 ∧ b ≥ 1 ∧ a ≥ q + r) P 5 = (a = a 0 ∧ b = b 0 ∧ r ≥ 0 ∧ q ≥ 1 ∧ b ≥ 1 ∧ a + 1 ≥ b + q + r) P 6 = (a = a 0 ∧ b = b 0 ∧ r ≥ 0 ∧ q ≥ 0 ∧ b ≥ r + 1 ∧ a ≥ q + r)
The relational summary σ of the div procedure given by P 6 at the unique exit point of the procedure is:

σ div = (a = a 0 ∧ b = b 0 ∧ r ≥ 0 ∧ q ≥ 0 ∧ b ≥ r + 1 ∧ a ≥ q + r)
We have the precondition a 0 ≥ 0 in σ div . Instead of just recovering the precondition a 0 ≥ 0, we obtained the stronger constraint a ≥ q + r. This suggests that using a widening limited by the procedure precondition is not only a technique to preserve and recover the precondition in the procedure summary, and that beyond its initial intended objective it is an effective general precision improvement technique.

Conclusion

We saw that the relational semantics of a procedure can be derived from the usual state collecting semantics, using additional variables to denote initial values of variables. It is not really new [START_REF] Irigoin | Semantical interprocedural parallelization: An overview of the PIPS project[END_REF] in principle but a new general formalization that we did not find elsewhere.

The relational semantics of a procedure can be used in a forward analysis to discover abstract input-output relations between the possible values of procedure parameters at a given control location and their initial values at procedure entry. The abstract relation discovered at the exit node of a procedure is an approximate relational summary of the procedure behavior.

The approach described in this chapter forms the basis of a general framework to compute relational procedure summaries, which can be instantiated with any relational abstract domain.

We presented the application of this approach to Linear Relation Analysis and the convex polyhedra abstract domain to obtain relational procedure summaries which are sets of linear constraints. Finally, we discussed the importance of preconditions for precise procedure summaries. Preconditions should be the object of a special attention, and be handled carefully, notably through the use of a limited widening.

A single convex polyhedron is generally not precise enough due to convex approximation. It can not distinguish very different behaviors of procedures. In the next chapter, we propose to compute disjunctive relational procedure summaries driven by preconditions. Disjunctive relational summaries will be finite sets of abstract relations, representing different procedure behaviors, represented by elements of a relational abstract domain.

Chapter 5 Disjunctive Relational Procedure Summaries

We presented the computation of relational summaries based on the relational collecting semantics of procedures. We shown that relational collecting semantics can be defined in terms of the usual collecting semantics of procedures by introducing variables denoting initial values of parameters. As it can be expected, concrete relational summaries are not computable by machine in general. We departed from them and described how abstract relational summaries can be computed effectively, using a classical analysis by abstract interpretation over a relational abstract domain, which is able to discover approximations of relations over states.

We had a particular focus on the use of trace partitioning to compute approximations of reachable relations over states and taking care of preconditions. In this chapter, we propose to refine the partitioning by distinguishing different calling contexts, represented by preconditions. We can see calling contexts as sets of possible initial states of procedures, giving initial values to procedure parameters. Since preconditions are subsets of initial states, they provide a simple way to represent calling contexts.

Usual abstract domains are generally not closed under disjunction, like octagons and convex polyhedra. In a sense, not being able to express disjunctions, joining together disjuncts into a single, possibly greater abstract value, is the essence of abstraction. It is thus quite natural in order to have more precise procedure summaries to consider explicit disjunctions of abstract relations.

Restrictions must be applied to be able to compute on such disjunctions. Moreover, to be able to use a disjunctive procedure summary to analyze a procedure call, the values of actual parameters must determine which disjunct of the summary applies. Thus distinct disjuncts should have disjoint sources.

We present a method to compute disjunctive relational summaries of procedures based on a recursive refinement of preconditions enabling each disjunct to express the behavior of a procedure on a distinct set of calling contexts. We give several heuristics for automatic precondition partitioning. We also show how disjunctive summaries are used to get the abstract effect of a call in the calling procedure.

Finally, we apply our approach to summaries of recursive procedures. As recursive procedures depend on themselves from an interprocedural point of view, the summary of a recursive procedure is computed in terms of itself.

Motivating Example

We consider the very simple abs procedure given in Figure 5.1, which computes the absolute value of its parameter x and stores the result in r. Its control-flow graph is given on the right-hand side. We compute a relational summary of the abs procedure using Linear Relation Analysis. Following the method presented in Chapter 4, we consider this system of abstract fixpoint equations in which a convex polyhedra P i is associated to each program node ν i :

void abs(int * r, int x) { if(x >= 0){ *r = x; } else { *r = -x; } } x ≥ 0? r := x x ≤ -1? r := -x ν 0 ν 1 ν 2 ν 3 ν 4 ν 5
P 0 = (r = r 0 ∧ x = x 0 ) P 1 = P 0 P 2 = (P 1 (x ≥ 0))[r := x] P 3 = (P 1 (x ≤ -1))[r := -x] P 4 = P 2 P 3 P 5 = P 4
We introduced additional variables x 0 and r 0 to denote the initial value of the parameters x and r respectively, and we added equality constraints x = x 0 and r = r 0 in P 0 to record the initial value of x and r. A classical Linear Relation Analysis gives the following results for P 2 , P 3 , and P 5 :

P 2 = (r = x 0 ∧ r = x ∧ r ≥ 0) P 3 = (r = -x 0 ∧ r = -x ∧ r ≥ 1) P 5 = (x = x 0 ∧ r ≥ x ∧ r ≥ -x)
Since ν 5 is the unique exit node of the abs procedure, its relational summary σ abs = P 5 is as follows:

σ abs = (x = x 0 ∧ r ≥ x ∧ r ≥ -x)
This is a rather weak summary for such a simple procedure, more so considering the precise relations r = x and r = -x discovered respectively in P 2 and P 3 . This loss of precision is due to the join operator applied for P 4 , which computes the convex hull of P 2 and P 3 . The convex polyhedra abstract domain, as most numerical abstract domains, is not able to represent exactly the disjunction P 2 ∨ P 3 , as it is not a convex set.

Although very simple, the abs procedure has two distinct behaviors, represented by P 2 and P 3 , which are triggered depending on the initial value of the parameter x respectively when x ≥ 0 and when x ≤ -1 initially. A precise procedure summary should express properly these two behaviors in a separate way.

Thus we can see on this simple procedure that we need to keep separate behaviors of procedures which are distinct in some sense, to obtain precise procedure summaries. We propose a method to compute disjunctive relational summaries of procedures, each element of the summary being an abstract input-output relation, denoting a distinct procedure behavior.

Disjunctive Refinement of Abstract Relations

We described in Chapter 4 how to compute procedure summaries following the relational collecting semantics of procedures. These relational summaries were made of a single abstract input-output relation, represented by an element of a relational abstract domain. We use this approach as a basis for the computation of disjunctive relational summaries.

General Framework

We present the refinement of abstract input-output relations into finite disjunctions of abstract relations. A disjunctive refinement of the abstract relation ρ (S i , S j ), for S i , S j ∈ δ , is a finite set R = {r 1 , ..., r m } of abstract relations such that:

1. ∀k ∈ {1, ..., m}, r k ρ (S i , S j ) 2. ∀k 1 , k 2 ∈ {1, ..., m}, k 1 = k 2 ⇒ γ(src (r k 1 )) ∩ γ(src (r k 2 )) = ∅ 3. m k=1 γ(src (r k )) = γ(S i )
We assume that, for a given procedure p, we have an abstract partition δ = {S 1 , ..., S n } of the set S of states of the procedure p. This means that each member S i ∈ δ of the abstract partition δ denotes a part of the set S of states, and that the set {γ(S i ) | S i ∈ δ } of the concretizations γ(S i ) of each member S i ∈ δ is a partition of S.

The abstract relation ρ (S i , S j ), for some S i , S j ∈ δ , is the abstract transitive closure between S i and S j , denoting all procedure behaviors starting from a state described by S i and ending in a state described by S j . Each disjunct r k of the refinement R = {r 1 , ..., r m } of the abstract relation ρ (S i , S j ) is itself an abstract relation, representing a part of these behaviors.

Soundness of the Refinement

We first give a soundness condition for each disjunct r k ∈ R. We require that each disjunct r k must be included in the original abstract relation ρ (S i , S j ) where:

r k ρ (S i , S j )
This ensures that each disjunct r k ∈ R denotes a part of the procedure behaviors in the original abstract relation ρ (S i , S j ).

Partition of the Source

As we intend to use disjunctions of abstract relations to represent distinct procedure behaviors directed by the initial values of parameters triggering that behavior, the sources of each disjunct r k ∈ R must be distinct in some way.

The concrete sources γ(src (r k )) of each disjunct r k ∈ R of the refinement R must be disjoint. This is expressed in Definition 5.2.1 by the following requirement:

∀k 1 , k 2 ∈ {1, ..., m}, k 1 = k 2 ⇒ γ(src (r k 1 )) ∩ γ(src (r k 2 )) = ∅
The concretization function γ of a Galois connection is known to be a morphism for the greatest lower-bound operator:

∀d 1 , d 2 ∈ R , γ(d 1 d 2 ) = γ(d 1 ) ∩ γ(d 2 )
Thus we have fortunately that:

∀r 1 , r 2 ∈ R , src (r 1 ) src (r 2 ) = ⊥ ⇔ γ(src (r 1 )) ∩ γ(src (r 2 )) = ∅
Therefore in practice we can check that the abstract sources of the disjuncts are disjoint in the abstract domain:

∀k 1 , k 2 ∈ {1, ..., m}, k 1 = k 2 ⇒ src (r k 1 ) src (r k 2 ) = ⊥
Finally, the set {src (r k ) | r k ∈ R} of the abstract sources of the disjuncts r k ∈ R of a refinement R must cover the abstract source S i of the original abstract relation ρ (S i , S j ), from the point of view of the concrete domain in order to encompass all possible initial states of the procedure. This is why the set {src (r k ) | r k ∈ R} of abstract sources of the disjuncts must be an abstract partition of S i .

Example 5.2.1. We give an example of disjunctive refinement of an abstract relation represented by convex polyhedra. We consider the abstract relation r 1 given in Example 4.3.1, which is defined as follows:

r 1 = (x = x 0 + 1 ∧ y = y 0 ∧ z 0 ≥ z ∧ y ≥ 23 ∧ x ≥ 1)
The abstract source src (r 1 ) of r 1 is:

src (r 1 ) = (x 0 ≥ 0 ∧ y 0 ≥ 23)
We may want to refine r 1 according to the initial value of x compared to the initial value of y, leading to two cases for the initial values of parameters x and y, which can be expressed by the inequality constraints x 0 < y 0 and x 0 ≥ y 0 . Thus we can refine r 1 into r 1,1 and r 1,2 , according to the constraints x 0 < y 0 and x 0 ≥ y 0 as follows:

r 1,1 = r 1 (x 0 < y 0 ) = (x = x 0 + 1 ∧ y = y 0 ∧ y ≥ x ∧ z 0 ≥ z ∧ y ≥ 23 ∧ x ≥ 1) r 1,2 = r 1 (x 0 ≥ y 0 ) = (x = x 0 + 1 ∧ y = y 0 ∧ z 0 ≥ z ∧ y ≥ 23 ∧ x ≥ y + 1)
We denote this refinement as R = {r 1,1 , r 2,2 }. The disjuncts r 1,1 and r 1,2 have disjoint abstract sources src (r 1,1 ) and src (r 1,2 ):

src (r 1,1 ) src (r 1,2 ) = (x 0 < y 0 ∧ y 0 ≥ 23 ∧ x 0 ≥ 0) (x 0 ≥ y 0 ∧ y 0 ≥ 23 ∧ x 0 ≥ 0) = ⊥
We should also see that the concretizations γ(src (r 1,1 )) and γ(src (r 1,2 )) of the abstract sources of r 1,1 and r 1,2 are covering γ(src (r 1 )) as follows:

γ(src (r 1,1 )) ∪ γ(src (r 1,2 )) = {(x 0 , y 0 , z 0 ) ∈ Z 3 | x 0 ≥ 0 ∧ y 0 ≥ 23} = γ(src (r 1 ))
and naturally, as stated earlier, the abstract sources src (r 1,1 ) and src (r 1,2 ) are disjoint in the abstract domain:

src (r 1,1 ) src (r 1,2 ) = ⊥

Disjunctive Refinements as Conjunctions of Implications

A disjunctive refinement R = {r 1 , ..., r m } of an abstract relation ρ (S i , S j ) is a finite set of possibly smaller abstract relations r 1 , ..., r m which can be considered as formulas over variables denoting initial values and variables denoting current values. The disjunctive refinement R can be seen as a disjunctive formula constraining the initial and current values of variables:

R = m k=1 r k
Since a disjunctive refinement is directed by the abstract sources of its members which are disjoint, it can be also seen as a conjunction of implications: The partitioning of preconditions is used to define disjunctive relational procedure summaries consisting of a finite set of abstract input-output relations. Each abstract relation, as a member of the procedure summary, describes a distinct part of the procedure behavior. It is separated from the others by the particular precondition leading to that behavior. They are covering collectively the global precondition of the procedure. By using an abstract partition of the global precondition, we ensure that all possible initial states of the procedure are accounted for.

R = m k=1 (src (r k ) ⇒ r k )

Refinement by Precondition Partitioning

We give below a definition of disjunctive relational summaries based on a partitioning of the global precondition. Definition 5.2.3 (Disjunctive relational summary). Let p be a procedure represented by a transition system (S, ρ, I, E). Let δ I = {I 1 , ..., I m } be a finite abstract partition of the global precondition I of the procedure p. The disjunctive relational summary R p = {r 1 , ..., r m } of the procedure p with respect to the abstract partition δ I of the precondition I is defined as:

∀r k ∈ R, r k = ρ (I k , E )
Example 5.2.2. We computed previously the following relational summary for the abs procedure:

σ abs = (x = x 0 ∧ r ≥ x ∧ r ≥ -x)
The abs procedure has the implicit precondition I = Z 2 which is abstracted by I = in the convex polyhedra abstract domain.

x ≥ 0?

r := x x ≤ -1? r := -x ν 0 ν 1 ν 2 ν 3 ν 4 ν 5 P 2 = (r = x 0 ∧ r = x ∧ r ≥ 0) P 3 = (r = -x 0 ∧ r = -x ∧ r ≥ 1)
We can distinguish the two procedure behaviors expressed by P 2 and P 3 according to the sign of the x parameter, respectively when x ≥ 0 and when x ≤ -1. We construct an abstract partition δ I = {I 1 , I 2 } of the global precondition I of the abs procedure:

δ I = {I 1 , I 2 } I 1 = (x 0 ≥ 0) I 2 = (x 0 ≤ -1)
The summary σ abs of the abs procedure is an approximation of the transitive closure ρ (I , E ) with ρ (I , E ) σ abs . The summary σ abs can be refined into R = {r 1 , r 2 } where abstract relations r 1 and r 2 are obtained by computing approximations of ρ (I 1 , E ) and ρ (I 2 , E ).

Computing summary member r 1 with precondition I 1

We compute the summary member r 1 as a sound approximation of ρ (I 1 , E ). A Linear Relation Analysis of the abs procedure under the precondition I 1 = (x 0 ≥ 0) gives the following results:

P 0 = (r = r 0 ∧ x = x 0 ∧ x ≥ 0) P 1 = (r = r 0 ∧ x = x 0 ∧ x ≥ 0) P 2 = (r = x 0 ∧ x = x 0 ∧ r ≥ 0) P 3 = ⊥ P 4 = (r = x 0 ∧ r = x ∧ r ≥ 0) P 5 = (r = x 0 ∧ r = x ∧ r ≥ 0)
We have P 3 = ⊥, thus the program point ν 3 is unreachable under I 1 . It is worth to observe and to keep in mind that cleverly chosen preconditions can make unreachable a given program location. The summary member r 1 under precondition I 1 is given by P 5 as follows:

r 1 = (r = x 0 ∧ r = x ∧ r ≥ 0)
Computing summary member r 2 under precondition I 2

Similarly, we compute r 2 as an approximation of ρ (I 2 , E ) using Linear Relation Analysis. The summary member r 2 under precondition I 2 is as follows:

r 2 = (r = -x 0 ∧ r = -x ∧ r ≥ 1)
Disjunctive Relational Summary of the abs Procedure

We computed a disjunctive relational summary R = {r 1 , r 2 } of the abs procedure directed by an abstract partition δ I = {I 1 , I 2 } of its global precondition I = Z 2 with I 1 = (x 0 ≥ 0) and I 2 = (x 0 ≤ -1). The disjunctive relational summary R of the abs procedure is:

R = {r 1 , r 2 } r 1 = (r = x 0 ∧ r = x ∧ r ≥ 0) r 2 = (r = -x 0 ∧ r = -x ∧ r ≥ 1)

Abstract Effect of a Call

We show how to use the disjunctive summary R of a procedure p to get the abstract effect of a call to p in the calling procedure. We denote as π : R → R a parameter passing mechanism which renames, in abstract relations, formal parameters into actual parameters.

Definition 5.2.4 (Abstract Effect of a Call). Let p be a procedure represented by a transition system (S, ρ, I, E). Let R = {r 1 , ..., r m } be a disjunctive relational summary of the procedure p. The abstract effect of a call to the procedure p situated between T i and T j with a parameter-passing mechanism π : R → R is defined as follows:

ρ(T i , T j ) = r k ∈R π(r k )
Example 5.2.3. The effect Q of the call statement abs(&r,&x) on the convex polyhedron Q = (x ≥ 10) is computed as follows:

Q = (∃x 0 , Q[x/x 0 ] r 1 ) (∃x 0 , Q[x/x 0 ] r 2 ) = (∃x 0 , (x 0 ≥ 10) (r = x 0 ∧ r = x ∧ r ≥ 0)) (∃x 0 , (x 0 ≥ 10) (r = -x 0 ∧ r = -x ∧ r ≥ 1)) = (r = x ∧ r ≥ 10) ⊥ = (r = x ∧ r ≥ 10)

Application to Linear Relation Analysis

We are now interested in discussing some specific considerations for the construction and manipulation of disjunctive relational summaries, particularly their application to Linear Relation Analysis with abstract relations being represented by convex polyhedra.

Disjunctive Polyhedral Summaries

Let p be a procedure represented by a transition system (S, ρ, I, E). Let X be the finite set of the formal parameters of p. Let I be its polyhedral abstract global precondition with I = α(I ).

A disjunctive relational summary of the procedure p is a finite set of convex polyhedra R = {R 1 , ..., R m } where each member R k ∈ R of the summary is a convex polyhedron representing an abstract input-output relation. The finite set {I k } k∈{1,...,m} of convex polyhedra defined as:

∀k ∈ {1, ..., m}, I k = src (R k ) = ∃X, R k
constitutes a finite abstract partition of the global precondition I of the procedure p. This is analogous to what we introduced for general abstract relations, but now stated specifically for convex polyhedra. We should note that the abstract source operation src is expressed through the variable elimination operation on convex polyhedra.

Polyhedron Transformer of a Procedure Call

Let q be a procedure calling the procedure p. We assume that a call to the procedure p in the procedure q is denoted as a special edge (n i , n j ) between two program nodes n i and n j in the control-flow graph of the procedure q. This configuration is illustrated in Figure 5.2. The procedure p has a finite sequence X = (x 1 , .., x n ) of formal parameters and the calling procedure q supplies the finite sequence A = (a 1 , .., a n ) of actual parameters in the call to procedure p, which is labeled on the edge (n i , n j ) as follows:

call p(a 1 , ..., a n )
For a discussion of our assumptions regarding procedure parameters, see Section 4.2.2. We assume that the length of the sequence A of actual parameters supplied by the calling procedure q is equal to the length of the sequence X of formal parameters expected by the called procedure p. We also assume that actual parameters are distinct variables.

Procedure

q n i n j call p(a 1 , ..., a n ) Procedure p Summary R = {R 1 , ..., R m } Figure 5
.2: Graphical illustration of a procedure q calling a procedure p with actual parameters A = (a 1 , ..., a n ).

We denote as Q i the convex polyhedron associated to n i in the calling procedure q right before the call to p and as Q j the convex polyhedron associated to n j just after the call. In order to avoid a top-down analysis of the procedure p each time the control-flow edge (n i , n j ) is examined, we compute the convex polyhedron Q j after the call in terms of the summary R of p and the convex polyhedron Q i discovered before the call.

The application of a disjunctive summary involves a substantial amount of variable renaming to encode the parameter passing mechanism.

Given the sequence A = (a 1 , ..., a n ) of actual parameters, we introduce an auxiliary sequence A 0 = (a 0 1 , ..., a 0 n ) of variables denoting the values of actual parameters just before the call to the procedure p.

We transform the calling context Q i into a property Q i [A/A 0 ] on variables denoting actual parameters before the call.

Then, we match A 0 variables denoting initial values of actual parameters in the input property Q i [A/A 0 ] with the X 0 variables denoting initial values of formal parameters in each summary member R k ∈ R. We denote as R k [X 0 /A 0 ] the renaming, in a summary member

R k ∈ R, of each variable x 0 ∈ X 0 into a 0 i ∈ A 0 .
Finally, we also rename the X variables denoting final values of procedure parameters into variables denoting the values of actual parameters after the call to p. For each summary member R k ∈ R, we compute:

R k [X 0 /A 0 ][X/A]
Definition 5.2.5 (Polyhedron Transformer of a Procedure Call). The convex polyhedron Q j associated to n j after the call to the procedure p in the procedure q is defined as:

Q j = m k=1 (∃A 0 , Q i [A/A 0 ] R k [X 0 /A 0 ][X/A])
It collects the contributions of each summary member R k of the called procedure p, which are constrained by the calling context Q i . A renaming of variables ties actual parameters in the caller with the formal parameters of the called procedure.

Partition Refinement

We saw how to compute disjunctive relational summaries of procedures given an abstract partition of the global precondition of a procedure. This abstract partition of the global precondition will be sometimes simply termed the partition of the summary.

The precondition of a procedure is the set of admissible initial values of parameters. We get this global precondition either in a very simple way, from the the types of parameters, or right from above, in the form of a user-given annotation. In the worst case, or in the absence of any specific property of initial values of parameters, the global precondition of a procedure can be chosen soundly to be the universal condition.

When we defined disjunctive relational summaries, we assumed that we had, given before our hands, an abstract partition of the global precondition of a procedure. We discuss how the abstract partition of the global precondition can be computed effectively.

Different objectives can be pursued regarding the computation of partitions of preconditions. They are used to separate procedure behaviors which would involve a great loss of precision if they would have been represented by a single element of a relational abstract domain.

Thus we may be interested in choosing an abstract partition which tries to maximize the separation of highly different procedure behaviors, in order to avoid that loss of precision. We also want to limit the size of disjunctive relational summaries, with a regard to the number of analyses which are computed for a given procedure. So, we have here, as in some other occasions, a tradeoff between expressivity and cost. We propose several heuristics corresponding to various intents and tradeoffs.

Refinement Heuristics

We can split recursively the global precondition of a procedure, into new preconditions, which when taken back together, cover all the behaviors which were previously described by the global precondition alone.

We say that these new preconditions refine the global precondition of the procedure. We call refinement the process of splitting a precondition and refinement heuristic the algorithm or scheme describing this process. Definition 5.3.1 (Refinement of a Precondition). Let p be a procedure described by a transition system (S, ρ, I, E). Let I be the global abstract precondition of the procedure p, such that I ⊆ γ(I ). Let A be an abstract precondition of p such that A I . Two preconditions A 1 and A 2 are said to refine the precondition A if they are covering A as follows:

A 1 A 2 = A
We do not require in the previous definition that the two preconditions A 1 and A 2 don't intersect since we are only interested in their covering of the abstract precondition A in order for the admissible initial states denoted by A to be preserved by the refinement.

Refinement According to Local Reachability

We present a first refinement heuristic called refinement according to local reachability. Its overall principle is to refine a precondition according to the abstract relation discovered at a given control point of a procedure, and particularly according to the information relative to the conditions under which that control point may be possibly reachable or not.

Intuitively, for a given abstract relation r k discovered at a program point ν k in a procedure p, the abstract source src (r k ) of r k is a property on initial values of parameters, which have been propagated along paths in the procedure during a relational analysis. Since the abstract source src(r k ) is a property on the initial states of the procedure p, it is thus a precondition of p. More precisely, the abstract source src(r k ) is a necessary abstract precondition for the program point ν k to be reachable in the procedure p.

Complementable Abstract Values

We want to characterize procedure behaviors where a given control point is not reachable. We believe that, for some well-chosen control points in the procedure, the separation of procedure executions according to whether that particular program point is reachable or not can lead to great insights on the procedure behavior. We present the principles enabling that separation.

As the abstract precondition I k = src (r k ) is a necessary precondition for the control point ν k to be reachable, we would like to compute a precondition under which ν k is unreachable as some sort of negation of I k . This negation operation is the complementation of an abstract value, and the values for which such a complement value exists are said to be complementable. Definition 5.3.2 (Complementable abstract value). Let (D , , , , ⊥, ) be an abstract domain related to a concrete domain (D, ⊆, ∪, ∩, ∅) by a Galois connection (α, γ). An abstract value d ∈ D is said to be complementable if there exists an abstract value d ∈ D termed its complement such that:

1.

d d = ⊥ 2. γ(d ) ∪ γ(d ) = D
We can note that d being disjoint from its complement d implies that this is also the case in the concrete domain, such that γ(d

) ∩ γ(d ) = ∅.
d 1 = (x < y) d 1 = (x ≥ y) d 2 = (x < C) d 2 = (x ≥ C)
where C is a constant

d 3 = (2x + 3y ≤ z + t) d 3 = (2x + 3y ≥ z + t + 1)

Refinement of the Global Precondition

As before, we denote as I k = src (r k ) the necessary abstract precondition for a control point ν k in the procedure p to be reachable. A sufficient precondition I for ν k to be unreachable in the procedure p can be obtained if there exists a complementable abstract value s ∈ D containing I k with I k s defined as:

I = I s
For the convex polyhedra abstract domain, it means that the complementable abstract value s is an half-space, in which I k is included, since only half-spaces are complementable for convex polyhedra. Therefore s can be a constraint of the convex polyhedron I k . The member S k of the abstract partition δ of the set S of states of the procedure p can be the set of all states associated to a given control location ν k in p. In that case r ∇ (I , S k ) is the abstract relation discovered by a classical relational analysis at ν k . We only use the abstract relation r k discovered at a given control location ν k by a relational analysis to refine the precondition I , hence the term of refinement according to local reachability.

Algorithm

The refinement according to local reachability can be seen as consisting of the following steps:

1. Analyze the procedure p with a classical relational analysis, starting with an abstract precondition I . We denote as {r k } k=1,..,n the results discovered for each control point ν 1 , ..., ν n of the procedure p. 2. Choose a control point ν k in the procedure p such that r k = ⊥. 3. Choose a separating abstract value s ∈ D , which is complementable, such that src(r k ) s , for which the following properties hold:

I = I s = ⊥ I = I s = ⊥
We hold the intuition that the reachability of some well chosen control points in a procedure, and the conditions leading to it, denote interesting cases of the procedure behavior. With respect to callers of the procedure, we would like that calling contexts have an empty intersection with as much summary members as possible, to lessen the loss of precision during the computation of the effect of a call.

Refinement According to the Summary of a Called Procedure

In the previous heuristic, we compute a refinement of the precondition of a procedure p from the results of an analysis of p, with the intent to separate, by an explicit disjunction of calling contexts, some interesting behaviors of p, with the hope that they may represent typical cases of the procedure usage by its potential callers.

The effect of a call to a procedure with a disjunctive summary R = {σ k } k=1,...,m defined in 5.2.5 involves a least upper-bound in the calling procedure which is likely to lose precision. Thus it can be interesting to refine the partitioning of the caller to split this least upper-bound according to the disjunctive summary of the called procedure.

Applicability of Summary Members

We are interested in deriving conditions under which a given summary member σ k is applicable at a call site in a caller, with respect to the possible values of actual parameters.

A summary member σ k ∈ R of a procedure p is an abstract input-output relation, respectively between initial and final values of formal parameters of the called procedure p. The abstract source src (σ k ) is thus a condition on the formal parameters of the procedure p for σ k to be applicable. More properly, the formal parameters satisfy the property tgt (σ k ) at the end of an execution of the procedure p, if their initial values satisfy the condition src (σ k ).

From the point of view of the caller, the actual parameters satisfy the property π (tgt (σ k )) under the condition π (src (σ k )) where π is a parameter-passing mechanism. We can say that the effect on actual parameters in the caller, described by π (σ k ), only happen under the condition π (src (σ k )), on the values of actual parameters just before the call. Let us denote as J k = π (src (σ k )) the condition on actual parameters for σ k to be applicable at a given call site in the calling procedure.

Refinement of the Global Precondition

We want to refine the abstract precondition I ∈ D of the caller according to whether the summary case σ k is applicable or not.

Let n i be a control point in a procedure calling the procedure p just before the call to p. The control point n i will also be termed a call site to the procedure p. This situation is illustrated in Figure 5.2.

Using a classical relational analysis, r i is the abstract relation discovered at n i before the call p under the abstract precondition I . Then I k = src (r i J k ) is a necessary precondition of the caller for the condition J k to be satisfiable, and thus for the summary case σ k to be applicable at the call site n i .

We thus have a way to express the applicability of a summary case σ k of a called procedure in terms of a precondition I k of the caller.

As for the refinement according to local reachability, we can separate the executions of the caller in which the summary case σ k is applicable, from the executions in which it is not, by splitting the abstract precondition I of the caller according to a complementable abstract value s ∈ D such that I k s . The condition I k is entirely contained in s and thus the summary case σ k is applicable, J k is satisfied, when s holds. As a consequence, conversely, the summary case σ k do not apply when the complement s is satisfied.

We can split the precondition I of q into two new preconditions I and I according to the separating value s and its complement s . The separation of I into I and I is defined as: I = I s I = I s Definition 5.3.4 (Refinement According to the Summary of Called Procedures). Let p be a procedure with a disjunctive relational summary R p = {σ k } k=1,...,m . Let q be a procedure represented by a transition system (S, ρ, I, E) calling the procedure p. Let I be the abstract global precondition of the procedure q where γ(I ) = I. Let π : D → D be the parameter-passing mechanism corresponding to the call of p.

Let σ k ∈ R p be a member of the summary of p and let J k denote the precondition of σ k with J k = π (src (σ k )). In the calling procedure q, I k = src (r ∇ (I , J k )) is a necessary precondition of q for J k to be satisfiable and the condition for σ k to be applicable in the calling procedure q. If s ∈ D is a complementable abstract value such that:

I k s I k = I s = ⊥ ∧ I k = I s = ⊥
then I and I are refining the global precondition I of the procedure q. The condition I is a sufficient precondition of q for J k to be unsatisfiable.

We denote as RSCP k (R p , I ) = {I , I } a refinement of the abstract precondition I of a calling procedure according to the summary case σ k ∈ R p of the summary R p of the called procedure p.

Algorithm

The refinement of the abstract precondition I of a procedure q according to the summary of a called procedure p can be seen as consisting of the following steps:

1. Analyze the calling procedure q with a classical relational analysis, starting with an abstract precondition I . We denote as {r c } c=1,...,n the results obtained for each control point of the procedure q. 2. Choose a control point c in the procedure q located before a call to the procedure p, such that r c = ⊥. 3. Choose a member σ k ∈ R p of the disjunctive summary R p of the called procedure p. 4. Compute J k = π (src (σ k )) and I k = src (r ∇ (I , J k )). 5. Choose a separating abstract value s ∈ D , which is complementable, such that I k s , for which the following properties hold:

I = I s = ⊥ I = I s = ⊥
An example of refinement according to summaries of called procedures is given in 5.5.

Iterative Refinement

We presented two heuristics in the previous sections to refine the global precondition of a procedure. The refinement according to local reachability and the refinement according to the summaries of called procedures are embodying different ways to compute an abstract partition of a precondition. These partitioning heuristics can be used iteratively, in a repeated fashion, to obtain more and more refined abstract partitions of the global precondition.

Our proposal is to build the summary of a procedure as a sequence of analyses, working on more and more refined partitions of the global precondition. Each analysis starts on a refined abstract precondition, obtained by one of our partitioning heuristics, and its results are used in turn by the heuristics, to split further the precondition. Once the procedure has been analyzed according to each member of the current abstract partition,

Chapter 5

Disjunctive Relational Procedure Summaries the partitioning heuristics are used to derive a new abstract partition, by refining the preconditions, using the analysis results obtained at the current step.

The disjunctive relational summary of the procedure is constructed by collecting the abstract relations discovered at the exit point of the procedure, respectively under each precondition in the current abstract partition. If the procedure has several distinct exit points, the abstract relations discovered at these exit points may be collapsed into a single relation by the join operator of the relational abstract domain. As the abstract partition of the global precondition of the procedure is refined further, the disjunctive summary computed for the procedure becomes itself more and more refined and precise.

The iterative construction of procedure summaries can be seen as a sequence of steps. We can denote as P ( ) = {I ( ) k } k=1,...,m the abstract partition of the global precondition of a procedure at the -th step. We start initially with P (0) = {I } containing only the global abstract precondition I . At subsequent steps, for each , we analyze the procedure with a relational analysis respectively for each precondition I ( ) k in the current abstract partition P ( ) , computing the abstract relations {r ( ) k } k=1,...,m as a result, which are then used to refine P ( ) into P ( +1) through the refinement techniques presented before.

Algorithm

We present the iterative construction of procedure summaries in a more rigorous way, in the form of the pseudocode given in Algorithm 1.

Algorithm 1 Construction of the disjunctive summary of a procedure p by iterative refinement of the global abstract precondition I . The BUILD SUMMARY procedure computes a disjunctive relational summary of a procedure p with a global abstract precondition I ∈ D .

The computation of a disjunctive summary of the procedure p works iteratively as a sequence of steps. Each step produces a disjunctive summary S ( ) of p, according to a current abstract partition P ( ) of the global precondition of p. The current abstract partition P ( ) is then possibly refined by one of the partition refinement heuristics presented earlier, which is denoted as REFINE in the above pseudocode, and which should be instantiated by the actually used heuristic, such that refinement according to local reachability (denoted as RLR) or refinement according to summaries of called procedures (denoted as RSCP). A new abstract partition P ( +1) is constructed, which will be used in the next step.

During an -th step of the BUILD SUMMARY procedure, the next abstract partition P ( +1) is set to be empty initially, at line 6, and then, in a pointwise way, for each I k in the current partition P ( ) , the procedure p is analyzed under the precondition I k at line 8 by some classical relational analysis, such as LRA, which provides r ( ) k as a result. If we assume that there is an abstract partition δ = {S 1 , ..., S m } of the set S of states of the procedure p and that each S i ∈ δ is the set of states associated to some control point n i in the procedure p, then the abstract relation discovered by the relational analysis at point n i can be expressed as r ( )

k (I k , S i ).
The analysis results r ( ) k are used by the refinement heuristic denoted by REFINE at line 9, possibly producing a set of new abstract preconditions refining the current abstract precondition I k . There are two possible outcomes for the result Ref of the refinement heuristic:

1. The refinement criteria of the heuristic used are satisfied by the current precondition I k and the abstract relations r ( ) k discovered for the procedure p and the refinement heuristic produces a set Ref = {I , I } of new abstract preconditions refining the precondition I k . 2. In the case where the heuristic can not refine the precondition I k , when its refinement criteria can not be satisfied in any way, then it returns a singleton set containing only the precondition I k itself, with Ref = {I k }, indicating that no refinement of I is possible by the chosen heuristic. The result of the refinement heuristics denoted by Ref is then added to the next abstract partition P ( +1) at line 10.

Termination of the Refinement

This iterative refinement process can continue for a while, as it is not guaranteed to terminate in general. However, since the disjunctive summary S ( ) of the procedure p computed at the end of each -th step is sound, this refinement process can be stopped arbitrarily at any step. From a correctness standpoint, the termination of the BUILD SUMMARY procedure is therefore not an issue. It is thus only a matter of desired precision and expressivity of the resulting disjunctive summary, for the refinement process to be continued and for the refinement steps to be further pursued.

Moreover, for any practical purposes, we would want to have reasonably-sized summaries, particularly regarding the number of necessary analyses for a given procedure. Each summary member adds an additional abstract value that will potentially become an operand of the join operator, which is costly for convex polyhedra, when computing the effect of call statements in callers.

There is a tradeoff that must be made in practice regarding the maximum cardinality of a disjunctive summary that we allow to be constructed by the BUILD SUMMARY procedure. Since the refinement process can be stopped after any step and the computed summary still being sound, we can just stop the refinement process whenever the current computed summary S ( ) exceeds this fixed maximum cardinality. The maximum cardinality of a disjunctive summary is considered to be a parameter of our approach in practice, that will be denoted as θ. We will term as θ-limiting the technique consisting of stopping the refinement process whenever the size of the summary becomes equal to the θ parameter.

The refinement heuristics that we proposed earlier attempt to refine an abstract precondition using the results of a relational analysis of the procedure, by searching for a control point n i at which some refinement criterion is satisfied. Usually, many control points of the procedure can satisfy the refinement criterion, producing potentially different refinements of the precondition, with various levels of interest and usefulness.

Because we wanted our refinement heuristics to be as generic as possible, we did not place any formal requirement on the choice of such a control point in the case where several distinct points could satisfy the heuristic criterion. One may choose for example, to refine repeatedly a precondition according to the same control point in the procedure. This is especially why, in the presence of loops, we can not guarantee in general that the iterative refinement process terminates.

We should note however, that the refinement process terminates if we restrict ourselves to choose at most once a given control point along a chain of successive refinements of an abstract precondition I . This is especially the case, as we do so in practice, if we examine once only control points which are direct successors of conditions in the procedure.

Ensuring the Monotonicity of the Refinement

By splitting a precondition, we intend to express more precisely the behavior of a procedure specialized to these two new preconditions. We hoped intuitively that a relational analysis would provide more precise results given more precise preconditions. However, this is not guaranteed because of the non-monotonicity of the widening operator.

Thus at a step of the iterative refinement in the BUILD SUMMARY procedure, it is both sound and interesting to use, in the relational analysis of the procedure p at line 8, a widening limited by the result r ( -1) obtained at the previous step. The limited widening ∇ ensuring the monotonicity of the refinement process is defined as:

∀r 1 , r 2 ∈ D , r 1 ∇ r 2 = r 1 ∇r 2 if = 0 (r 1 ∇r 2 ) r ( -1) if ≥ 1
where ∇ is the widening operator used by the underlying relational analysis, which can be itself a limited widening.

Using such a limited widening is especially interesting for the construction of summaries of recursive procedures, and avoids the difficulties addressed in [START_REF] Apinis | How to combine widening and narrowing for non-monotonic systems of equations[END_REF] regarding nonmonotonic systems of fixpoint equations.

Example 5.3.2. We compute a disjunctive relational summary of the div procedure, which was presented in Section 4.3.3.

The relational analysis of the div procedure, starting from the abstract precondition I = (a 0 ≥ 0 ∧ b 0 ≥ 1), provides for the branches of the loop condition at program points void div(int a, int b, int * q, int * r) { assume(a >= 0 && b >= 1); 1: *q = 0; *r = a; 2: while 3:

(*r >= b) { 4:

*r = *r-b; *q = *q + 1; 5: } 6:}

P 1 = (a 0 ≥ 0 ∧ b 0 ≥ 1 ∧ a = a 0 ∧b = b 0 ∧ q = q 0 ∧ r = r 0 ) P 2 = P 1 [q := 0][r := a] P 3 = P 2 P 5 P 4 = P 3 (r ≥ b) P 5 = P 4 [r := r -b][q := q + 1] P 6 = P 3 (r ≤ b -1)
4 and 6, the following solutions:

P 4 (I ) = (a = a 0 ∧ b = b 0 ∧ r ≥ b ∧ q ≥ 0 ∧ b ≥ 1 ∧ a ≥ q + r) P 6 (I ) = (a = a 0 ∧ b = b 0 ∧ r ≥ 0 ∧ q ≥ 0 ∧ b ≥ r + 1 ∧ a ≥ q + r)
The program point 4 is right at the entry of the while loop in the div procedure and the program point 6 is at the exit of the while loop. Since the while loop is the main control structure of interest in the div procedure, we believe that the entry and the exit of the while loop, at program points 4 and 6 respectively, can be relevant control points to refine the abstract precondition I , following the spirit of the refinement according to local reachability. We are interested in the conditions, on the initial values of the procedure parameters, which can make these control points potentially reachable or conversely, unreachable. These conditions can be derived from the sources of the abstract relations discovered at program points 4 and 6, represented respectively by the convex polyhedra P 4 (I ) and P 6 (I ).

The projection of these solutions on the variables denoting initial values of parameters are as follows:

src (P 4 (I )) = (a 0 ≥ b 0 ∧ b 0 ≥ 1) src (P 6 (I )) = (a 0 ≥ 0 ∧ b 0 ≥ 1)
We have at program point 6 that src (P 6 (I )) = I , thus it can not induce any refinement of I . However, we have the interesting constraint a 0 ≥ b 0 in src (P 4 (I )) at program point 4. More importantly, we have src (P 4 (I )) = I , thus we can try to apply the criterion of refinement according to local reachability at program point 4.

We can choose the constraint s = (a 0 ≥ b 0 ) as a complementable abstract value to refine I . As s is a constraint of src (P 4 (I )), then src (P 4 (I )) is included in the half-space represented by s , and thus src (P 4 (I ))

s . We can refine the abstract precondition I into I which are defined as follows:

I (1) 1 = I s = (a 0 ≥ b 0 ∧ b 0 ≥ 1) s = (a 0 < b 0 ∧ a 0 ≥ 0) Chapter 5
Disjunctive Relational Procedure Summaries

I (1) 2 = I s = (a 0 < b 0 ∧ a 0 ≥ 0)
We can obviously check that the criterion of the RLR heuristic holds as we have both I corresponds to the case where the loop is entered at least once and I

(1) 2 corresponds to the case where the loop is never entered. Then, we analyze the div procedure using Linear Relation Analysis under the new preconditions I respectively. We get the following results for program points 4 and 6:

P 4 (I (1) 1 ) = (a = a 0 ∧ b = b 0 ∧ r ≥ b ∧ q ≥ 0 ∧ b ≥ 1 ∧ a ≥ q + r) P 6 (I (1) 1 ) = (a = a 0 ∧ b = b 0 ∧ r ≥ 0 ∧ q ≥ 0 ∧ q + r ≥ 1 ∧ b ≥ r + 1 ∧ a + 1 ≥ b + q ∧ a ≥ b) P 4 (I (1) 2 ) = ⊥ P 6 (I (1) 2 ) = (a = a 0 ∧ b = b 0 ∧ b -1 ≥ a ∧ a ≥ 0 ∧ q = 0 ∧ r = a)
We can use these results to further refine the partitioning of the global abstract precondition I . We can apply again the RLR heuristic. The projection of these solutions on the variables denoting initial values of parameters are:

src (P 4 (I (1) 1 )) = (a 0 ≥ b 0 ∧ b 0 ≥ 1) = I (1) 1 src (P 6 (I (1) 1 )) = (a 0 ≥ b 0 ∧ b 0 ≥ 1) = I (1) 1 src (P 4 (I (1) 2 )) = ⊥ src (P 6 (I (1) 2 )) = (a 0 < b 0 ∧ a 0 ≥ 0) = I (1) 2
The abstract sources src (P 4 (I can not be further refined. Finally, the partition of the global abstract precondition I of the div procedure is P = {I

2 }. The disjunctive summary S = {R 1 , R 2 } of the div procedure associated to the partition P has thus two members R 1 and R 2 computed as follows:

R 1 = P 6 (I

1 ) R 2 = P 6 (I

2 ) The disjunctive relational summary S = {R 1 , R 2 } of the div procedure is:

R 1 = (a = a 0 ∧ b = b 0 ∧ r ≥ b ∧ q ≥ 0 ∧ b ≥ 1 ∧ a ≥ q + r) R 2 = (a = a 0 ∧ b = b 0 ∧ r ≥ 0 ∧ q ≥ 0 ∧ q + r ≥ 1 ∧ b ≥ r + 1 ∧ a + 1 ≥ b + q ∧ a ≥ b)

A Last Improvement: Postponing Loop Feedback

The summary S of the div procedure was partitioned according to whether the loop is entered at least once, which is the situation represented by R 1 , or never entered, which is represented by R 2 . However, in the R 1 case, if the loop is entered at least once, then q should be incremented at least once and we should have at least q ≥ 1. As we can see in R 1 , this is a fact missed by the analysis. More specifically, the convex polyhedron R 1 is not included in the half-space denoted by the constraint q ≥ 1.

We could recover this fact by systematically unrolling once each loop that gives rise to such a partitioning. So, in our example, we could first unroll once the while loop and get the constraint q ≥ 1 by a Linear Relation Analysis performed afterward. We propose however another, cheaper solution, based on trace partitioning. The problem comes from the least upper-bound computed at loop entry, as denoted in the abstract fixpoint equation:

P 3 = P 2 P 5
which is then followed in the abstract equation for P 6 by the test on the loop condition:

P 6 = P 3 (r ≤ b -1)
The loss of precision caused by the least upper-bound operator happens before the test r ≤ b -1 has any chance to improve the result. The solution consists in permuting the least upper-bound and the test, computing instead P 6 as follows:

P 6 = (P 2 (r ≤ b -1)) (P 5 (r ≤ b -1))
Using this new abstract equation for P 6 , the summary member R 1 becomes:

R 1 = (a = a 0 ∧ b = b 0 ∧ a 0 ≥ b 0 ∧ b 0 ≥ 1 ∧ r ≥ 0 ∧ q ≥ 1 ∧ b ≥ r + 1 ∧ a + 1 ≥ b + q + r)
We now have in R 1 the constraint q ≥ 1 which was lost by the previous analysis. Furthermore, once again, we recovered more precision than expected, since in addition to finding q ≥ 1, the constraint a + 1 ≥ b + q has been strengthened into a + 1 ≥ b + q + r, which ties nicely together all parameters of the div procedure.

We should note that this rewriting of the system of abstract fixpoint equations can be also obtained by a program transformation applied on the procedure, transforming each loop of the form while c do S into a do-while loop if c {do S while c} guarded by the condition c. This transformation, often applied by compilers, is called loop inversion.

Therefore, beyond the particular example, our postponing of loop feedback can be a general precision improvement technique for loops.

Summaries of Recursive Procedures

The relational abstract interpretation of recursive procedures was proposed a long time ago in [START_REF] Cousot | Static determination of dynamic properties of recursive procedures[END_REF][START_REF] Cousot | Compositional separate modular static analysis of programs by abstract interpretation[END_REF][START_REF] Halbwachs | Détermination automatique de relations linéaires vérifiées par les variables d'un programme[END_REF]. It involves the use of widening, since the summary of a recursive procedure depends on itself. Moreover, a collection of mutually recursive procedures must be analyzed simultaneously, with widening applied to a cut-set of their call graph.

In this section, we show on a simple example how our technique can be applied to the construction of the disjunctive relational summary of a recursive procedure. Since the procedure is recursive, its summary will have to be used to analyze procedure calls during its own construction, and thus this will present an opportunity to refine the procedure summary according to itself. In its own recursive way, it will illustrate the refinement according to the summary of a called procedure.

Example 5.5.1. The f91 procedure is an implementation of the well-known 91 function defined by John McCarthy in [START_REF] Manna | Formalization of properties of functional programs[END_REF][START_REF] Manna | Properties of programs and partial function logic[END_REF], which is a classical test case for the analysis of recursive functions. For simplicity in this example, we do not duplicate parameters, knowing that x is a value parameter, whose value is thus never changed, and that y is a pure result parameter, whose initial value is never accessed. The polyhedral summary R(x, y) of the f91 procedure can be defined by the following system of abstract fixpoint equations: R(x, y) = P 1 P 2 P 1 = (x ≥ 101 ∧ y = x -10) P 2 = (x ≤ 100 (∃t, R(x + 11, t) R(t, y)))

The summary R is used in its own definition in the abstract equation defining P 2 since there are two recursive calls to the f91 procedure. We can use a classical Linear Relation Analysis to compute approximate solutions of this system of abstract fixpoint equations. The global abstract precondition I of the f91 procedure is I = . Without partitioning and after one widening step, we get:

P 1 = (x ≥ 101 ∧ y = x -10) P 2 = (x ≤ 100 ∧ y + 9 ≥ x ∧ y ≥ 91) R (0) = (x ≤ y + 10 ∧ y ≥ 91)
We can use the refinement according to local reachability to refine the global abstract precondition I . We compute the abstract sources of P 1 and P 2 and we get:

src (P 1 ) = (x ≥ 101) src (P 2 ) = (x ≤ 100)
Since the abstract source src (P 1 ) = (x ≥ 101) of P 1 is a single linear constraint, it is a complementable abstract value that we can use to split the precondition I . We refine the global abstract precondition I into two new preconditions I We analyze the f91 procedure with respect to this obvious partitioning, under each new precondition I

P 1 (I (1) 2 ) = ⊥ P 2 (I (1) 2 ) = (x ≤ 100 ∧ y ≥ 91) R (1) (I (1) 2 ) = (x ≤ 100 ∧ y ≥ 91)
The results are not much better, we still have only the inequality y ≥ 91 for the value of the parameter y in R (1) (I

(1)
2 ). We refined the summary of the f91 procedure according to local reachability and our source of interesting control points for refinement has dried out. No control point satisfies the refinement criterion of the RLR heuristic anymore.

The summary of the f91 procedure can be refined further according to the summary of the called procedure, which is here the f91 procedure itself. We can refine the precondition I which are defined as follows:

I (2) 1 = (90 ≤ x ≤ 100) I (2) 2 = (x ≤ 89)
We obtain the following disjunctive summary for the f91 procedure:

R (1) (I (1) 1 ) = (x ≥ 101 ∧ y = x -10) R (2) (I (2) 1 ) = (90 ≤ x ≤ 100 ∧ y = 91) R (2) (I (2) 2 ) = (x ≤ 89 ∧ y = 91)
This our most precise summary for the f91 procedure. We now have precise constraints on the value of each parameter in every summary member. We have particularly that y = 91 in both R (2)

(I (2) 1 ) and R (2) (I (2)
2 ). Even if there are seemingly two cases in the behavior of the f91 procedure, as denoted explicitly by the two parts of the if statement, our disjunctive summary of the f91 procedure features three cases. Thus our approach was able to uncover non-trivial procedure behavior which was not explicitly written in the procedure definition.

Conclusion

Procedures can commonly have very different behaviors, which are not precisely expressed by a single element of a relational abstract domain like convex polyhedra. We extended the approach presented in Chapter 4 to compute disjunctive relational summaries of procedures based on a partitioning of a procedure precondition. Disjunctive summaries are finite sets of abstract relations represented by elements of a relational abstract domain.

Chapter 5

Disjunctive Relational Procedure Summaries Several partitioning heuristics are given to compute automatically an abstract partition of a precondition by iterative refinement. We also proposed a last improvement to summary computation itself to improve the precision of summaries. Since recursive procedures are often not supported by existing interprocedural analysis, we shown that our approach can discover interesting disjunctive summaries for recursive procedures. Our approach computes an analysis of a procedure for each precondition in the summary partition. Thus we may wonder how it compares in practice with respect to other interprocedural analysis. We give some experimental results in Chapter 6 using the mars static analyzer.

Chapter 6 Implementation and Experiments

We describe in this chapter the design and implementation of our static analysis tool, called mars. The mars (Mars Abstract interpretation Research System) system is a static analysis framework for the analysis of C programs by abstract interpretation, with numerical relational abstract domains like convex polyhedra. With a strong emphasis on modularity and separation of concerns, enabling the change of multiple aspects of an analysis, the mars static analysis system has been designed to foster the experimentation of new interprocedural analyses, new iteration strategies and new abstract domains. We present also some experiments of our approach, using the mars static analyzer on a set of benchmark programs.

The mars Static Analyzer

The mars static analyzer is organized as a collection of tools computing numerical invariants of programs written in a significant subset of C. A frontend tool based on Clang [START_REF] Lattner | LLVM: A Compilation Framework for Lifelong Program Analysis & Transformation[END_REF] and LibTooling translates the abstract syntax tree of each C source file passed as input into the mars intermediate representation. The analyzer tool of mars, which is called mars, computes numerical invariants at each program point of interest in the intermediate representation. The implementation of numerical abstract domains, is provided by the Apron library [START_REF] Jeannet | Apron: A library of numerical abstract domains for static analysis[END_REF].

The mars intermediate representation is the common exchange format between the different tools. It is generated by the marsc frontend tool from a C source file given as input, which can be then processed by the mars analyzer tool. The results computed by the analyzer tool are associated to intermediate representation objects, such as program nodes and procedures.

The mars intermediate representation is designed specifically to ease the implementation of new analyses by abstract interpretation. It is tailored to the needs of numerical analyses such as Linear Relation Analysis. At the same time, it provides also a general representation of programs, capable of representation many programming constructs commonly found in imperative languages like C. With numerical abstract interpretation in mind, the mars intermediate representation eliminates the unnecessary features usually found in compiler frameworks, such as LLVM IR, and provides a clean idealized view of programs to numerical static analyses.

More specifically, programs are collections of procedures represented by a control-flow graph which is not based on an SSA-form, in order to offer high-precision source traceback information associated to analysis results.

Another key objective of the design of mars is to provide very precise source locations, tracing every entity in the mars intermediate representation back to the original C source code as given by the user, including across complex preprocessor usage, benefiting from the rich location information available in the Clang AST (Abstract Syntax Tree). It contrasts with other open-source static analysis frontends such as CIL [START_REF] Necula | Cil: Intermediate language and tools for analysis and transformation of c programs[END_REF], which takes as input C programs which have already been processed by the C preprocessor. The source locations given by CIL are only relative to the preprocessed C source. A more detailed presentation of the mars intermediate representation can be found in 6.3.

C programs given as inputs are significantly processed by the marsc frontend to generate the intermediate representation. The mars analyzer tool is implemented in the OCaml programming language and consists of approximately 4000 lines of code. The marsc frontend tool, which is based on Clang, is implemented in C++ and contains approximately 20000 lines of code on its own, excluding Clang itself.

Basic Usage

We describe some basic usage of the mars tools to provide a brief practical overview of our static analysis system.

A C file named program.c is translated into the mars intermediate representation by the marsc frontend using the command:

marsc program.c
The marsc tool creates an output directory, named by default out-program.c, in the current working directory. The output directory holds the intermediate representation of the input program encoded in the Json (Javascript Common Object Notation) format, along with all the results computed for that program and the files produced by any analysis of the program. The output directory serves as a common storage location in the user filesystem for the mars tools and as the single source of truth for a given program.

The mars analyzer tool can be used to analyze the program using the intermediate representation generated previously and possibly previous analysis results stored in the output directory. It is run using the following command:

mars -o out-dir -t analysis_name -m main

where the output directory out-dir for the program is specified by the -o out-dir option, the name of the particular analysis to be run is given by the -t analysis name option and the name of the program entry procedure is given by the -m main option.

Analysis results can be found in the output directory encoded in Json, or depending on the analysis implementation, displayed as an annotated C source file on the standard output.

Design and Implementation

The mars system is structured as a collection of tools based on a common set of OCaml modules. We give an overview of how these tools work together in Figure 6

Abstract Domains

We assume that the abstract domain is a lattice. The operators of the abstract domain are given classically as functions in the abstract domain module, as specified by the Domain signature given in Figure 6

Scheduler

A module providing an iteration strategy for the AbstractInterpreter functor is termed a Scheduler. Scheduler modules must be conforming to the Scheduler signature, which is given in Figure 6.4.

A scheduler module provides an extract function which is called by the abstract interpreter to get the next program node to be examined during an analysis, deciding of the order in which program nodes are visited. The Scheduler has access to the map associating the current abstract value to a given program node, as computed so far by the abstract interpreter. It can thus base its decision on abstract values associated to nodes and express non-trivial iteration strategies such as the guided static analysis technique [START_REF] Gopan | Guided static analysis[END_REF]. After the update of a node, the abstract interpreter calls the schedule function, with a boolean parameter indicating whether the abstract value of the current node has changed, which triggers the update of the successors of the current node.

The default scheduler module of mars uses the information given by Bourdoncle's algorithm [START_REF] Bourdoncle | Sémantiques des langages imperatifs d'ordre superieur et interpretation abstraite[END_REF][START_REF] Bourdoncle | Efficient chaotic iteration strategies with widenings[END_REF] on strongly-connected components of a procedure, with a priority queue, to decide of the exploration order of program nodes.

We made the iteration strategy an explicit parameter of the AbstractInterpreter functor as we wanted to experiment with various ways to explore new paths and nodes in a program, to improve analysis precision, which was the subject of our previous work [START_REF] Boutonnet | Improving the results of program analysis by abstract interpretation beyond the decreasing sequence[END_REF]. The iteration strategy is usually not a changeable parameter in modular denotational static analyzers such as [START_REF] Miné | Design of a modular platform for static analysis[END_REF], which are based on a recursive exploration of the abstract syntax tree of procedures.

Transfer Function Module

A Transfer module defines a transfer function eval node for the evaluation of nodes in a procedure over some abstract domain. The signature which must be satisfied by a Transfer module is given in Figure 6.5.

Along with the incoming abstract value to the current node, the eval node function must be given a proc data data structure which can be used to store procedure summaries. An interprocedural analysis, such as our approach, will store the computed procedure summaries in proc data, which are implemented by the Summary module, and that the matching Transfer module will be able to use for the evaluation of call statements. A strictly intraprocedural analysis on the other side can use a dummy proc data structure, parameterized by the NoSummary.t type (which is defined to be unit).

The mars Intermediate Representation

We want analyses to be free from concerns about some features of real-world languages such as C and particularly memory manipulation constructs like pointer dereferencing and pointer arithmetics.

We consider that memory manipulation constructs, particularly operation on pointers, should be handled by specialized pointer and alias analyses, transforming a procedure accessing memory through pointers into a procedure with abstract memory locations, manipulated through scalar variables and references. It enables numerical analyses to focus on their main concern, which is the analysis of numerical statements in a procedure. We implement such an analysis, in a simple way for the time being, in the marsc frontend.

Abstract Syntax

A program in the mars intermediate representation is a collection of procedures.

Procedures p ∈ P rocs

A procedure p can be seen formally as a tuple of the form:

p = (id, form, d v , g)
where id ∈ Id is the name of the procedure, form ∈ Decl p is a sequence of formal parameter declarations, d v ∈ Decl v is a sequence of local variable declarations and g ∈ CFG is the control-flow graph of the procedure.

Formal Parameter Declaration form ∈ Decl p Formal parameters declarations follow the following rule:

form ::= | id : pmode t; form

The mars Intermediate Representation

A declaration of a formal parameter id is of the form id : pmode t where pmode is the parameter-passing mode of the parameter id and t is its type. For simplicity, parameters are passed by reference.

Parameter Mode pmode ∈ P M odes

The mode of a formal parameter indicates whether, a given parameter is either a pure-value parameter (in mode), a pure-result parameter (out mode) or a value-result parameter (in-out mode).

P M odes = {in, out, in-out}

The value of a pure-value parameter can be only used but not modified, the value of a pure-result parameter can not be used in the procedure before being set and the value of value-result parameter can be both used and modified in the procedure.

Local Variable Declaration d v ∈ Decl v

A sequence of declarations of local variables in a procedure is of the following form:

d v ::= | id : t; d v Control-Flow Graphs g ∈ CFG
The control-flow graph of a procedure is a graph (N, E) where:

• The finite set N of nodes is made of three types of nodes: entry nodes, junction nodes and statement nodes. • E ∈ N × N is the set of control-flow edges. Each node has a single output, possibly leading to several successor nodes. There are no explicit control-transfer instructions. Classical test nodes are split into several conditions appearing in statement nodes. Their associated transfer functions intersect their argument with the condition of the test.

We define the function nsuccs : N odes → P(N odes) associating to a node the set of its successor nodes and the function npreds : N odes → P(N odes) associating to a node the set of its predecessors.

∀n ∈ N odes, nsuccs(n) = {s ∈ N | (n, s) ∈ E} npreds(n) = {p ∈ N | (p, n) ∈ E}

Entry Nodes Entries

An entry node n ∈ Entries has no predecessor node and a single successor node.

∀n ∈ Entries, npreds(n) = ∅ ∧ |nsuccs(n)| = 1

Statement nodes Stmts

A statement node n ∈ Stmt has a single predecessor node and possibly many successor nodes.

∀n ∈ Stmts, |npreds(n

)| = 1
Statement nodes contain a sequence of statements interpreted sequentially.

Statements can be of one of the following kind:

• Deterministic assignment: x := e where e is an expression.

• Non-deterministic assignment: x := undet. The transfer function associated to a non-deterministic assignment discards all information available on the variable x in its argument. • Assume statement: assume cond. The transfer function associated to an assume statement intersects its argument with the condition cond. The non-deterministic assignment x := undet can be used to handle conservatively in the intermediate representation the unsupported constructs of the source language.

Junction nodes Junctions

A junction node can have several predecessor nodes.

∀n ∈ Stmts, |npreds(n)| ≥ 1

Translation of Tests

Semantic equations

With each node n k of the CFG, we want to associate a transfer function f k mapping the set of formal parameters of a procedure to a boolean vector of B 3 , such that for each parameter X, we have f k (X) = (X i , X c , X u ). We define f k from the individual transfer functions f 1 k , f 2 k and f 3 k , updating respectively the attributes X i , X c and X u as follows:

f k (X) = (f 1 k (X), f 2 k (X), f 3 k (X))

Entry Node

Let n k is an entry node. We define the transfer function f k as follows:

∀X, f k (X) = (tt, ff , ff )
It indicates that each parameter is equal to its initial value, and has neither been changed nor used.

Junction Nodes

Let n k is a junction node. We define the transfer function f k as follows:

∀X, f k (X) =   (n ,n k )∈E f 1 (X), (n ,n k )∈E f 2 (X), (n ,n k )∈E f 3 (X)  
The attributes X i and X c are true respectively, if they were also true at each predecessor node n . The attribute X u is true if it was true for at least once predecessor node.

Statement Nodes

Let n k be a statement node, with a condition C k and assignment statements:

(X 1 k := E 1 k , ..., X k k := E j k )
where (X 1 k , ..., X j k ) are formal parameters of the procedure. We define the predicates U(X) and C(X) for each parameter X such that:

• U(X) is true if and only if X appears either in the condition C k or in some expression E i k , which is if and only if the value of X is used in the node n k . • C(X) is true if and only if X is one of the assigned variables X i k , which is if X is assigned at node n k . Let n p be the unique predecessor node of the statement node n k . Then, the transfer function f k is defined as follows:

∀X, f k (X) = f 1 p (X) ∧ ¬C(X) , f 2 p (X) ∨ C(X) , f 3 p (X) ∨ U(X)

Experiments

We presented only tiny examples to illustrate our approach for which the partitioning of the precondition is obvious. However, in presence of more complex control structures, such as nested or successive loops, and when preconditions result from more involved invariants, the interest of our method for discovering relevant preconditions is more convincing.

More thorough experiments are necessary to validate our approach and in particular to answer the following questions.

1. Since we analyze a procedure several times to construct its summary, as required by the iterative refinement of its precondition, it is likely to be time-consuming. Thus it is interesting to measure to cost of summary construction with respect to the time hopefully saved by using the summary. 2. Precondition partitioning is a heuristic process, thus it is important to evaluate the precision lost or gained by using a disjunctive summary instead of analyzing the procedure for each calling context. Therefore our experiments consists in comparing our bottom-up approach computing disjunctive relational summaries of procedures with an analysis of inlined programs, both with respect to the analysis time and the precision of results. Several difficulties must be addressed first.

Most public benchmarks are not usable, since they contain very few numerical programs with procedures. For instance, in the SV-COMP benchmark1 , most numerical examples are inlined and the ALICe benchmark2 also contains only monolithic programs. For our assessment, we used the benchmark of the Mälardalen3 WCET research group, which contains various small and middle-sized programs, such as sorts, matrix computations and fft. Moreover, some programs of this benchmark were sometimes extended with auxiliary variables counting the number of executions of each block to help the evaluation of the execution time [START_REF] Boutonnet | The WCET analysis using counters -a preliminary assessment[END_REF]. These extensions, the name of which are prefixed with cnt are particularly interesting for us, since they contains more numeric variables and should stress the performance of our approach.

The comparison of results which are convex polyhedra is not straightforward. On one hand, we must decide which polyhedra to compare. The correspondence of control points between the inlined program and the structured program with procedures is not easy to preserve. In our experiments, we only compared the results at the end of the main program. Of course, for the comparison to be meaningful, the results on the inlined program must be first projected on the variables of the original program. On the other hand, while a qualitative comparison of two convex polyhedra is easy, by checking their inclusion in both directions, a quantitative comparison is more difficult. It could be achieved precisely by comparing their volumes, dedicated algorithms are available for that [START_REF] Barvinok | A polynomial time algorithm for counting integral points in polyhedra when the dimension is fixed[END_REF][START_REF] Clauss | Counting solutions to linear and nonlinear constraints through Ehrhart polynomials: applications to analyze and transform scientific programs[END_REF], but it is only possible for bounded polyhedra. In our assessment, besides a qualitative comparison, we only compare the number of constraints.

All our experiments are done using the convex polyhedra abstract domain. Widening is never delayed and decreasing sequences are limited to 7 terms. The analysis times are those obtained on an Intel Xeon E5-2630 v3 2.40Ghz machine with 32GB of RAM and 20MB of L3 cache running Linux. Table 6.1 compares our method with a standard LRA on inlined programs, in terms of analysis time, qualitative precision and number of constraints of results found at the exit points of the main procedures. The "# procs" column gives the number of procedures in each program and the "max. # calls" column gives the maximum number of call sites per procedure in a program. We denote as:

• t il the time in seconds for analyzing the inlined program.

• t ip the time in seconds for the interprocedural analysis of the original structured program. • P il the polyhedron result of the inlined analysis at the exit points of the procedure.

• P ip the polyhedron result of the interprocedural analysis at the exit points of the main procedure. • C il the number of constraints of P il .

• C ip the number of constraints of the polyhedron P ip . The qualitative results comparison is shown by column "cmp. res." which indicates whether the result P ip is better ( ), worse ( ), equal (=) or incomparable (<>) with respect to P il . The S column gives for each program the speedup of our method compared to standard LRA with inlining, defined as: S = Time for standard LRA with inlining/Time for disjunctive relational summaries where:

S = t il /t ip
Our method is significantly faster than standard LRA using inlining for 13 over 19 programs (≈ 68% of programs), with an average speedup of 2.9. The loss of precision is very moderate since only 1 over 19 programs, namely minver, has a less precise convex polyhedra at the exit node of the main procedure. Interestingly, our method also leads to precision improvements for some programs, such as janne complex, my sin and cnt minver, due to the use of disjunction, enabling a more accurate analysis of procedure behaviors. Moreover, those precision improvements are not necessarily obtained at the expense of analysis time, since the janne complex program has a more precise convex polyhedra at the exit of the main procedure, with a 60% increase in the number of constraints and has also the highest speedup with S = 15.34. Table 6.2 reports the computation times of the summary of each procedure in each program. The τ c column gives the fraction of the analysis time using our method spent during the computation of each procedure summary, defined as follows: τ c = Procedure summary comp. time/Program analysis time using rel. summ.

We can also note that the janne complex program, which has the highest speedup in Table 6.1, is consisting only of a single other procedure besides the main procedure. Thus the speedup given by our method is already noticeable on small programs, even with few procedures and few procedure calls. This is due to procedures being analyzed separately in smaller variable environments compared to the inlined program. Overall, our method is mostly faster than inlining when procedures have a much larger number of local variables compared to the number of parameters.

The summary construction time for small utility procedures, such as the my fabs, my sin, my cos and my log procedures, in the fft1 and cnt fft1 small (lower than 4ms) and often individually negligible with respect to the analysis time of the entire program (with τ c often lower than 1%). This suggests that our method could be particularly beneficial, in terms of analysis performance, for programs built on top of a collection of utility procedures or a library of such procedures, each procedure summary being computed only once and possibly used in many call contexts.

Our last experiment concerns the speedup of our interprocedural analysis with respect to the number of calls. Notice that the Mälardalen benchmark is not very favorable in this respect, since most procedures are called only once. Our analysis on the cnt ns program has a moderate speedup of 1.25. In order to observe the evolution of the speedup with the number of calls, we increase the number of calls to the foo procedure in the main procedure of the cnt ns program. The graph of Figure 6.9 shows the evolution of the analysis times of these successive versions, comparing our analysis with respect to standard LRA with inlining.

The analysis of the cnt ns program using our disjunctive relational summaries analysis becomes significantly faster than standard LRA with inlining when there are more than 2 calls to the foo procedure in the main procedure. Additionally, Fig. 6.9 shows that the analysis time of the cnt ns program using standard LRA with inlining grows exponentially in the number of calls to the foo procedure, while the analysis time using our method grows much slower when the number of calls is increasing. Figure 6.9: Analysis times of the cnt ns program when increasing the number of calls in the main procedure to the foo procedure.

Conclusion

We presented mars, a static analysis system designed and developed during this thesis with two main objectives: facilitate the development of new static analyses and providing high-quality source traceability information. The mars static analyzer uses its own intermediate representation designed specifically for numerical abstract interpretation. A frontend tool translates C programs into the mars intermediate representation from the abstract syntax tree provided by Clang. It also extracts traceability information given by the compiler frontend which locates in the source each individual part of intermediate representation. The mars static analyzer is based on a generic abstract interpreter allowing the decoupling of the abstract domain, the transfer functions used on this domain and the iteration strategy. These elements can be given independently as OCaml modules.

We conducted experiments of our modular analysis on a standard benchmark in the WCET community. First, we shown that the construction time of procedure summaries is often negligible with respect to the analysis time of the entire program. Then, we compared our approach with respect to an analysis of the entire program using inlining. We could be wondering whether the interest of using procedure summaries would be showing only on programs with a sufficiently large number of procedure calls. Even on small programs with few procedure calls, our method often provides a significant speedup compared to a classical analysis using inlining. When the number of calls increases, the analysis time of our method grows much slower than the duration of the analysis using inlining which grows exponentially.

A number of improvements could be implemented in the future:

• When computing disjunctive procedure summaries using the refinement according to local reachability, we examine the successors of test nodes to refine preconditions. Advanced heuristics could be designed to examine only the successors of tests which are deemed interesting in some sense to get precise summaries. • Similarly, when searching for a constraint in a convex polyhedron to refine a precon-dition, we currently examine all possible constraints and select one that satisfies the refinement criterion in no particular order. Heuristics could be proposed to select the most interesting constraints.

• We compute a relational analysis for each refined precondition when computing a disjunctive summary to take into account the effects of loops and widening. In practice, an analysis optimized for performance could avoid to reanalyze completely a procedure for each precondition by just splitting recursively the preconditions according to tests, at the expense of less precise summaries. • Disjunctive procedure summaries could be refined according to properties given by an alias analysis and different aliasing situations involving procedure parameters. A proper alias analysis should be implemented to improve the support of parameters of pointer type.

Part III Modular Analysis of Reactive Systems

Chapter 7

Analysis and Verification of Reactive Systems

In this part, we want to design a modular analysis of reactive systems for numerical properties. We give a brief overview of reactive systems in 7.1. We are especially interested in synchronous reactive programs. We present synchronous languages in 7.2 and a particular synchronous language called Lustre in 7.3. The compilation of synchronous languages to sequential code is discussed in 7.4. Under certain conditions, reactive components can be compiled modularly, where each component is implemented by a step procedure invoked inside a global infinite loop. We give in 7.5 a definition of the class of structured reactive programs that will be considered in the following chapters. Finally, we describe in 7.6 the state of the art regarding the analysis and verification of reactive programs.

Introduction to Reactive Systems

In the light of many foundational works [START_REF] Benveniste | The synchronous approach to reactive and real-time systems[END_REF][START_REF] Halbwachs | Synchronous programming of reactive systems[END_REF], reactive systems can be defined as systems continuously reacting to their environment, at a speed determined by their environment. They may receive inputs from the environment, such as sensor values or signals, and produce outputs in reaction to these inputs. They are called reactive by contrast with classical systems which are termed transformational systems, receiving their inputs at the beginning of their execution and delivering their results upon termination. Most industrial systems are reactive, such as control systems and process supervision systems. Communication and network protocols, human-machine interfaces are other examples of reactive systems. The reliability of reactive systems is often highly desirable or even critical, as it is wellknown that errors in the operation of reactive systems can have terrible consequences, such as the loss of human life or of massive amounts of money. The analysis and verification of reactive systems is thus of paramount importance. Therefore, we may want to either check that the system satisfies some given property, to ensure the safety of its operation, or to compute an approximation of the set of its reachable states.

A reactive system can be seen as computing a sequence of reaction steps, where in each step, current inputs are read, the system memory is updated, current outputs are computed and finally delivered to the environment of the system, which can be for example input-output devices. As such, a reactive program can be seen as a single, infinite, non-terminating loop, which implements the sequence of reaction steps. Each loop iteration consists in reading current inputs, calling a step function on the current inputs and the current memory, which returns the current outputs with a new memory. We give in Figure 7.1 an example of a loop representing a reactive program.

We denote as X the set of input variables, as Y the set of output variables and as M the set of memory variables. We denote as read the operation which consists in reading the current inputs and similarly, we denote as write the operation delivering the current outputs to the program environment. The step function is denoted by S.

M = M 0 ; loop { read(X); (Y, M ) = S(X, M ); write(Y ); }

Synchronous Languages

Synchronous languages [START_REF] Halbwachs | Synchronous programming of reactive systems[END_REF][START_REF] Benveniste | The synchronous approach to reactive and real-time systems[END_REF] have been designed to express deterministic, structured reactive programs. Synchronous programs are organized as collections of parallel reactive components. However, we should note that the parallelism between components of a synchronous program is only logical, being more of a logical concurrency, than an effectively parallel or distributed implementation, as synchronous programs are classically compiled into sequential programs.

The synchrony hypothesis considers that components react instantaneously to their inputs in a logical instant. Physical time disappears and time is seen as a sequence of discrete logical instants. Although such a reaction may involve many computations for its implementation, they are seen as atomic at a logical level. Synchronous programs have a uniquely defined behavior for every possible sequence of inputs, hence being deterministic, with no possibility of deadlock, thus being reactive, as the absence of deadlocks is guaranteed by rules enforced by compilers.

Synchronous languages come in different styles, such as the imperative languages Argos [START_REF] Maraninchi | Argos: an Automaton-Based Synchronous Language[END_REF], Esterel [START_REF] Berry | The Esterel synchronous programming language: design, semantics, implementation[END_REF], Mode Automata [START_REF] Maraninchi | Mode-automata: A new domain-specific construct for the development of safe critical systems[END_REF], SyncCharts [START_REF] André | Semantics of SyncCharts[END_REF], Statecharts [START_REF] Harel | Statecharts: a visual formalism for complex systems[END_REF], and the functional languages Lustre [START_REF] Halbwachs | The synchronous data flow programming language LUSTRE[END_REF] and Signal [START_REF] Leguernic | Programming real-time applications with Signal[END_REF]. Esterel is based on the parallel composition of processes with interrupts, communicating through the instantaneous broadcast of signals. Lustre and Signal are data-flow languages, based on data streams carrying boolean, integer or arbitrarily typed data at each instant at which they are defined. Streams are defined according to clocks which are themselves boolean streams.

Although our work can be applied to reactive programs in any synchronous language, we have a particular interest in the analysis of Lustre programs.

The Lustre Programming Language

A Lustre program defines its output variables and its memory variables as functions of its input variables and the previous value of its memory variables. An expression e t can be seen semantically as a function of discrete time, such that (e t ) t≥0 is a sequence of values for each instant t ≥ 0. Variables are defined by equations, such that the equation X = e means that the variable X is always equal to the expression e. In the data flow program represented in Figure 7.2, the variables X 1 , X 2 , Y 1 , Y 2 can be interpreted as functions of time:

Y 1 = 2 × X 1 + X 2 Y 2 = Y 1 + 1 × + 2 + 1 X 1 X 2 Y 1 Y 2
∀t ∈ N, Y 1 (t) = 2 * X 1 (t) + X 2 (t) ∀t ∈ N, Y 2 (t) = Y 1 (t) + 1
In Lustre, expressions are built from identifiers, constants, arithmetical and logical operations, along with two specific temporal operators:

• A delay operator pre, defined as follows:

∀t ≥ 1, (pre(E)) t = E t-1
At the initial reaction step, the value (pre(E)) 0 is set to a special value nil. • An initialization operator ->, giving an initial value to an expression at the initial reaction step, defined as follows:

(E->F ) 0 = E 0 ∀t ≥ 1, (E->F ) t = F t A Lustre program is structured into nodes.
A Lustre node is a subprogram implementing a reactive component, which defines output variables in terms of input variables, possibly containing memory variables.

Example 7.3.1. The Sum node represented in Figure 7.3 has an integer input incr, a boolean input reset and an integer output s. It computes the sum of the values of the incr input since the last instant at which reset was true, otherwise since the initial reaction step if reset has never been true.

The Sum node can be used in other nodes, such as in the equation mod7 = Sum(1, (pre(mod7) = 6)) which instantiates the Sum node with 1 as the increment value and reset it when the previous value was 6. The variable mod7 is thus the cyclic sequence of non-negative integers modulo 7.

node Sum (incr : int; reset : bool) returns (s : int); let s = 0 -> if reset then 0 else pre(s) + incr; tel;

Compilation of Synchronous Languages

Synchronous programs are classically compiled to sequential code, with a single step function implementing a reaction of the entire program. Such a step function is intended to be called inside an infinite loop, which is in charge of triggering reactions, reading inputs and writing outputs. The machine implementation of a step function in a sequential imperative language is often called a step procedure. The input variables incr and reset of the Sum node are passed by value to the sum step procedure, while the output variable s is passed by pointer to allow imperative updates. As we can see in the definition of the Sum node, the variable s is defined as being equal to zero at the initial reaction step, through the use of the initialization operator. The step procedure sum step tests the occurrence of the initial reaction step by a test on the value of a special boolean parameter init, which is true at the initial reaction step and false everafter. It is the responsibility of the external infinite loop to set appropriately the value of the init parameter.

Compilation of Synchronous Languages

Lustre allows the expression of hierarchy and node reuse by node calls in Lustre expressions, which can be used in the definition of other nodes. A single monolithic step procedure for the top-level node is classically obtained in the academic Lustre compiler by inlining all node calls.

Modular Compilation

Modular compilation is highly desirable in industrial compilers, such as in SCADE suite [START_REF] Ansys | SCADE Suite[END_REF], to avoid an intolerable increase in the size of the generated code due to the inlining of internal nodes.

However, modular compilation of synchronous programs is not possible in general, as noticed by Gonthier in [START_REF] Gonthier | Sémantiques et modèles d'exécution des langages réactifs synchrones : application à Esterel[END_REF], and as exemplified by the double copy node shown in Figure 7.5.

Example 7.4.2. The node double copy is a valid Lustre node, since it is equivalent to the set of equations z = x; y = z, although it can not be compiled in a modular way. The equations of the double copy node can be compiled either into the sequential statements v1 = t2; v2 = t1; or into v2 = t1; v1 = t2;, since there are two possible sequential orderings for the equations as they have no dependencies between each other. However, the ordering v1 = t2; v2 = t1; is not valid for the instantiation (y,z) = double copy(x,z) resulting in the statements y = z; z = x; where z is used before being defined. Conversely, the ordering v2 = t1; v1 = t1; is not valid for the instantiation (y,z) = double copy(z,x).

Thus the double copy node cannot be compiled independently of its usage and it is not possible to generate a single step procedure which can be called in every context.

In general, reactive components can not be compiled modularly, with a step procedure per component without considering the component environment.

Solutions have been proposed for the modular compilation of synchronous programs, either by enforcing restrictions on the ways components can be connected together, such as in SCADE, or by source code transformation [START_REF] Raymond | Compilation séparée de programmes Lustre[END_REF][START_REF] Lublinerman | Modular code generation from triggered and timed block diagrams[END_REF][START_REF] Pouzet | Modular static scheduling of synchronous data-flow networks: an efficient symbolic representation[END_REF][START_REF] Pouzet | Modular static scheduling of synchronous data-flow networks[END_REF].

In SCADE, the rule enforced to enable modular compilation is that every feedback loop must cross an explicit external delay operator pre. Such a restriction rejects some causally correct programs, such as the double copy node.

An alternative solution, between the inlining of all internal nodes and the rejection of some causally correct feedback loops was proposed in [START_REF] Raymond | Compilation séparée de programmes Lustre[END_REF][START_REF] Lublinerman | Modular code generation from triggered and timed block diagrams[END_REF][START_REF] Pouzet | Modular static scheduling of synchronous data-flow networks: an efficient symbolic representation[END_REF][START_REF] Pouzet | Modular static scheduling of synchronous data-flow networks[END_REF]. The decision problem associated to the modular compilation of a synchronous data-flow network into c atomic components, without restricting valid feedback loops, was shown to be NPcomplete in [START_REF] Lublinerman | Modular code generation from triggered and timed block diagrams[END_REF]. However, according to [START_REF] Pouzet | Modular static scheduling of synchronous data-flow networks: an efficient symbolic representation[END_REF], most real programs do not exhibit such a complexity. A symbolic encoding of the problem was proposed in [START_REF] Pouzet | Modular static scheduling of synchronous data-flow networks: an efficient symbolic representation[END_REF][START_REF] Pouzet | Modular static scheduling of synchronous data-flow networks[END_REF] in terms of input-output relations to obtain in polynomial time a decomposition of a node into atomic components which is optimal in some cases.

We will only consider in what follows structured reactive programs which can be compiled modularly.

Structured Reactive Programs

A reactive system can generally be considered to be made of a set of parallel components. Each component can be seen as a reactive system of its own, with its own memory, inputs and outputs, described by its own step function.

Structured reactive programs are sets of well-defined reactive components, where component implementations are independent from one another. We assume that components in a reactive program communicate solely by the means of inputs and outputs and a component can not manipulate directly the internal memory of a distinct component.

Formally, we consider a structured reactive program to be made of an ordered list (C 1 , ..., C n ) of reactive components. A reactive program has three pairwise-disjoint sets of global variables:

• A set X of global input variables • A set Y of

global output variables

• A set M of global memory variables For a set U of variables, we denote as V(U ) the set of valuations of variables in U . The step function S corresponding to the entire reactive program is such that

S : V(X) × V(M ) → V(Y ) × V(M ).

Reactive Component

Each component C i for i = 1, ..., n of a reactive program has three pairwise-disjoint sets of variables:

• A set X i of component input variables • A set Y i of component output variables • A set M i of component memory variables Each reactive component C i is implemented by a step function S i : V(X i ) × V(M i ) → V(Y i ) × V(M i )

which associates valuations of output variables and memory variables to a valuation of input variables and a previous valuation of memory variables.

The variables of a synchronous reactive data-flow component satisfy the following properties:

1. Each input of a component C i is either a global input of the reactive program, a global memory or the output of a previous component:

∀i ∈ {1, ..., n}, X i ⊆ X ∪ M ∪ 1≤j<i Y j 7.6 Structured Reactive Programs 2.
The memory of a component C i is local to that component. The set M i is disjoint from any other set of variables. 3. The outputs of each component are disjoint:

∀i, j ∈ {1, ..., n}, i = j ⇒ Y i ∩ Y j = ∅ 4.
Each global output and each global memory variable is the output of a component:

Y ∪ M ⊆ 1≤i≤n Y i 5.
Component output variables are used either as global output, global memory, or as input to another component:

1≤i≤n Y i ⊆ Y ∪ M ∪ 1≤i≤n X i
These properties on variables of a reactive program and its constituting components give restrictions on the form of structured reactive programs. Components are considered to communicate only through variables, at least from a high-level point of view, and the actual communication mechanism used in a given implementation should be reducible to variable manipulations.

Property 1 ensures that each input variable of a component has been properly written or computed before being read by that component. All variables must be defined once and only once, by a single component. In particular, as a kind of well-formedness condition, property 3 ensures that no two distinct components can write to the same variable. Property 4 ensures that the global outputs of the program are well-defined and property 5 states that all outputs of a component are used.

S 1 X 1 Y 1 S 2 X 2 Y 2 M 1 M 2 M

Analysis and Verification

Regarding reactive programs, experience shows as argued in [START_REF] Halbwachs | An experience in proving regular networks of processes by modular model checking[END_REF], that we are mostly interested in proving safety properties, or bounded liveness properties that can be reduced to safety properties, which can be expressed as sets of possible valuations of component variables.

Verification of Synchronous Programs and Observers

Classically, safety properties can be expressed as synchronous observers [START_REF] Halbwachs | Synchronous observers and the verification of reactive systems[END_REF], which are components receiving the inputs and the outputs of the component under verification and deciding at each reaction step if the property is satisfied or not, setting appropriately the value of an output variable giving the observer verdict.

A safety property can be verified on a reactive component by an analysis of the reachable states of the composition of the component to be verified with the observer of the safety property. The property is satisfied if the output variable of the observer is always true. Thus, the safety property is transformed into an invariant property of the composition of the component under verification with the observer.

Component C

Observer O outputs inputs ok Observers have the advantage over temporal logics that they can be expressed in the same language as the program under verification, and thus can be executed and tested.

Analysis of Synchronous Programs

The analysis of synchronous programs is classically performed on a control structure called a control automaton, which is a way to compile synchronous programs using a partial evaluation of boolean memory variables, as pioneered by Esterel [START_REF] Berry | The Esterel synchronous programming language: design, semantics, implementation[END_REF] v2 and v3 compilers. The academic Lustre compiler [START_REF] Raymond | Efficient Compilation of a Declarative Synchronous Language: the Lustre-V3 Code Generator[END_REF] is able to construct a boolean interpreted automaton and to minimize it on-the-fly by bisimulation [START_REF] Bouajjani | Minimal model generation[END_REF]. The transitions of the control automaton are labeled by tests on boolean and numerical variables, and by assignments of numerical variables. Such a control structure, in the case of purely-boolean control programs, allows the model checking of safety properties.

Model Checking of the Boolean Control Automaton

The control automaton can also be used as a boolean abstraction of a general synchronous program, by introducing free logical variables to represent tests on numerical variables, representing an over-approximation of the program behavior, which can then be verified by a model checker.

Analysis and Verification

Several tools based on model-checking have been developed (Lesar [START_REF] Ratel | Design and implementation of a formal verification tool for Lustre programs : the system Lesar[END_REF][START_REF] Halbwachs | Programming and verifying real-time systems by means of the synchronous data-flow programming language Lustre[END_REF], TempEst [START_REF] Olnhausen | Safety property verification of Esterel programs and applications to telecommunications software[END_REF], Xeve [START_REF] Bouali | Xeve, an esterel verification environment[END_REF]) to verify boolean safety properties on synchronous programs by an exploration of the state space of the control automaton, abstracting away the behavior of numerical variables. These techniques can fail to verify a property on synchronous programs with numerical variables, due to the over-approximation of the possible program behaviors.

More precisely, properties depending directly or indirectly on numerical variables can not be verified by model checking of the boolean control automaton. To alleviate these limitations, the Lesar model checker eliminates numerically unsatisfiable transitions in the control automaton before the model-checking itself. For linear constraints, efficient decision procedures are available, such as the emptiness test of convex polyhedra. This preprocessing restricts the boolean state-space to be explored by the model checker. However, the dynamic behavior of numerical variables is still ignored.

Linear Relation Analysis of Synchronous Programs

It was proposed in [START_REF] Halbwachs | Verification of real-time systems using linear relation analysis[END_REF] to perform a Linear Relation Analysis on the boolean control automaton of a synchronous program. As a result, a convex polyhedron associated with each state of the control automaton is obtained, representing an over-approximation of the set of reachable variable valuations at a given state for a forward analysis. We can also perform a backward analysis and obtain an over-approximation of the variable valuations leading to an erroneous state or a property violation. Numerical tests and assignments of numerical variables on transitions of the control automaton can be used to derive a system of fixpoint equations, partitioned according to boolean states, which is then solved using the standard widening operator.

Linear Relation Analysis can be used either to verify a given property, on the control automaton representing an observer composed with the program under verification, or for the discovery of the possible reachable states without an explicit proof objective, which can be applied to prove the absence of runtime errors such as arithmetic overflows.

A dynamic refinement of the control automaton, with respect to a property to be verified, was proposed in [START_REF] Jeannet | Partitionnement dynamique dans l'analyse de relations linéaires et application à la vérification de programmes synchrones[END_REF][START_REF] Jeannet | Dynamic partitioning in analyses of numerical properties[END_REF].

The Lack of Modularity

Either classical model checkers for synchronous languages, or Linear Relation Analysis for synchronous programs as presented in [START_REF] Halbwachs | Verification of real-time systems using linear relation analysis[END_REF], consider a monolithic control automaton obtained after inlining all internal components. Thus due to inlining, the resulting boolean control automaton can have an intractable size for large synchronous programs. The analysis results for a given component are not reused, and a sub-component can be analyzed many times if it is instantiated in several different contexts. Therefore a modular verification approach for synchronous reactive programs would be highly desirable.

SAT/SMT-based Model Checking

More recently, several approaches have been proposed for the model checking of safety properties of Lustre programs using SAT/SMT-based techniques, namely k-induction [START_REF] Bjesse | SAT-based verification without state space traversal[END_REF][START_REF] Bradley | SAT-based model checking without unrolling[END_REF].

Let N be a Lustre node modeled as a formula ∆(n) expressing an equational system of constraints describing the valuation of the variables of N at a given instant n in terms of the valuations at instants n, n -1,...,n -d where d is the maximum nesting depth of the pre operator in N .

Let P be a property expressed as a quantifier-free formula P (n) over the variables of N . We denote as ∆ t the formula obtained by replacing every occurrence of n by t in ∆(n) and as P t the formula obtained by replacing every occurrence of n by t in P (n).

We can prove that P is an invariant for N by k-induction if we prove that the two following statements are correct for some k ≥ 0:

∆ 0 ∧ ∆ 1 ∧ ... ∧ ∆ k |= P 0 ∧ P 1 ∧ ... ∧ P k ∆ n ∧ ∆ n+1 ∧ ... ∧ ∆ n+(k+1) P n ∧ P n+1 ∧ ... ∧ P n+k |= P n+(k+1)
The approach presented in [START_REF] Sheeran | Checking safety properties using induction and a SAT-solver[END_REF][START_REF] Abdulla | Designing safe, reliable systems using scade[END_REF] based on SAT-based k-induction is used for the model checking of boolean safety properties of Lustre programs in the Prover tool integrated with the SCADE suite.

Kind 2 [START_REF] Hagen | Scaling up the formal verification of Lustre programs with SMT-based techniques[END_REF][START_REF] Hagen | Verifying Safety Properties of Lustre Programs: An SMT-based Approach[END_REF][START_REF] Hagen | Scaling up the formal verification of Lustre programs with SMT-based techniques[END_REF][START_REF] Champion | The Kind 2 model checker[END_REF] is an SMT-based model checker to verify safety properties of finite and infinite state-space Lustre programs, using first-order logic with linear integer and real arithmetic. Kind 2 relies on several SMT solvers as backends to prove quantifierfree properties, which are expressed by the user in an extended dialect of Lustre, either as assume-guarantee contracts or as invariants. Backends are run concurrently and can cooperate to achieve a given proof goal. Kind 2 can also perform compositional reasoning over nodes, by allowing the user to give assume-guarantee contracts on some nodes, and by reusing the proven properties in these contracts during the verification of a hierarchy of nodes. Kind 2 also takes advantage of the capabilities of modern SMT solvers, which are incremental and backtrackable, able to return models and to compute unsatisfiable cores. An earlier experiment of the SMT-based model checking of Lustre programs was described in [START_REF] Franzén | Using satisfiability modulo theories for inductive verification of Lustre programs[END_REF].

Modular Abstractions of Lustre Nodes

The lack of modularity of earlier verification approaches, based on model checking or Linear Relation Analysis on a monolithic control automaton, can be tackled by computing abstractions of the behavior of Lustre nodes in a modular fashion, and to use these abstractions to compute invariants of Lustre programs. Then, a Lustre program can be verified for a given property of interest by computing an invariant of the program composed with an observer representing that property.

A modular abstraction of Lustre nodes by disjunctive invariants was proposed in [START_REF] Monniaux | Modular abstractions of reactive nodes using disjunctive invariants[END_REF], based on predicate abstraction, using quantifier elimination and SMT-solving. A finite set of predicates Π = {p 1 , ..., p m } over the variables of a Lustre program is considered. The approach computes disjunctive invariants of the form C 1 ∨ ... ∨ C n where each disjunct C i is a conjunction of predicates of Π with a bounded size. Such a disjunctive invariant follows the template: i m j=1 b i,j ⇒ p j and can be obtained by instantiating the b i,j booleans. The problem of finding a disjunctive invariant over the finite set Π of predicates is reduced to finding suitable values for the boolean variables b i,j . This problem is encoded into a quantifier-free formula F over the b i,j variables, which can be solved using an SMT-solver. A minimal disjunctive invariant, for a given template, can be obtained by iterative refinement.

Modular invariants of Lustre nodes encoded as Horn clauses are obtained in [START_REF] Garoche | Synthesizing modular invariants for synchronous code[END_REF] based on property-directed reachability [START_REF] Hoder | Generalized property directed reachability[END_REF], either by encoding modularly a synchronous program as a set of Horn clauses or by synthesizing a modular invariant from a monolithic invariant.

Conclusion

The analysis and verification of synchronous reactive programs is classically based on a monolithic boolean control automaton describing the entire program. It is constructed by inlining all node instantiations to get a single flat component. The modular structure of a reactive program into sub-components is completely lost. Using model-checking or Linear Relation Analysis, the analysis of the boolean control automaton involves rapidly for large programs an explosion of the automaton size and of the number of abstract states. Several approaches using SAT or SMT solvers for the modular verification of Lustre nodes have been proposed. They require a proof objective or a property to be verified.

To prove the absence of errors at runtime like arithmetic overflows, we need to prove automatically that program variables are always bounded, and it would be quite painful for users to provide those bounds manually in large systems. Thus we are interested in the automatic discovery of invariant properties of reactive programs, without requiring a proof objective, in a modular way.

In the next chapter, we propose a new approach toward a modular analysis of reactive systems, based on the computation of disjunctive relational summaries of step procedures. The summaries of step procedures will be used to construct a representation of components called Relational Mode Automata, designed specifically for analysis and providing several levels of abstraction of component behavior. The analysis results of a relational mode automaton can be used modularly to analyze larger systems made of other components without computing a product automaton. We will also give a way to tune the level of detail of a relational mode automaton to achieve different tradeoffs in analysis precision and performance.

Chapter 8

Towards a Modular Analysis of Reactive Systems using Relational Mode Automata

Reactive programs are usually structured as sets of components, cooperating together to implement the system behavior. If the implementation of a reactive program is not explicitly structured as such, it is quite convenient and natural to consider such a program as being made of distinct components. Reactive programs involve concurrency between the components, at the level of their logical structure, even if the actual implementation is not concurrent itself. Classically, synchronous programs are compiled into a single step procedure, in which all logical concurrency has been dealt away by a sequential scheduling of component reactions.

As we saw in Chapter 7, synchronous programs are classically analyzed in a monolithic fashion, either in the form of a step procedure implementing the whole program, or as a single control automaton, resulting from the synchronous composition of its components.

The structure of a reactive program as a system of components is completely lost in those approaches. There is no reuse of analysis results for components, which may be instantiated in multiple different contexts.

Existing approaches for the modular analysis of synchronous programs consider only Lustre programs, with an observer specifying explicitly the property to be checked. On one hand, they do not handle reactive programs where, as in real-world industrial cases, some components are implemented externally in a different language, such as C. This is especially necessary to access native features of the implementation platform, such as input-output devices. On the other hand, we would like to be able to not only verify, but also automatically discover properties of reactive programs. For example, discovering linear relations between the variables of a reactive program can be used to check if these variables are bounded at all times, for every possible input event, without having to give the actual bound manually. It can also be applied to the analysis of the Worst-Case Execution Time (WCET) of reactive programs [START_REF] Boutonnet | The WCET analysis using counters -a preliminary assessment[END_REF][START_REF] Raymond | Improving WCET evaluation using linear relation analysis[END_REF].

We propose in this chapter an approach for the modular analysis of reactive programs, where each component can be analyzed separately, to discover automatically relations between input, output and memory variables.

The Bounded Event Counter

We consider a very simple reactive program, which implements a bounded event counter, defined by the counter step procedure given in Figure 8 The bounded event counter receives two boolean inputs, reset and event, and returns an integer output cnt counting the number of occurrences of an event, denoted by the event variable, since the last reset, or since the first reaction step if no reset has been received yet. The output cnt stays at the same value when it reaches the counter capacity n, which is assumed to be a positive symbolic constant, until a reset is received. For simplicity, boolean variables are implemented as integer variables between 0 and 1. Alternatively, we could use an abstract domain combining boolean properties with convex polyhedra [START_REF] Jeannet | Partitionnement dynamique dans l'analyse de relations linéaires et application à la vérification de programmes synchrones[END_REF][START_REF] Bakhirkin | Extending constraint-only representation of polyhedra with boolean constraints[END_REF].

This may seem to be a simplistic example, however overflows of counter components have been the cause of a number of notable software bugs in critical systems. The Boeing Dreamliner 787 [START_REF] Administration | Airworthiness directives; the Boeing company airplanes[END_REF] had to be rebooted every 248 days, due to a counter overflow in the firmware of the Generator Control Units (GCUs), which are in charge of AC power management in the airplane. In order to prove the absence of arithmetic overflows in the counter step procedure, we must first guarantee that the output variable cnt remains bounded at all times. More specifically, the value of cnt must be always between 0 and n, for every possible value of n with n ≥ 1. We would like to obtain 0 ≤ cnt ≤ n at each reaction step in a modular fashion, without having to consider other components and without inlining of step procedures.

We can start by computing a classical Linear Relation Analysis on the step procedure and see what properties can be discovered.

The parameters init and event are boolean variables in the high-level definition of the counter component. From the knowledge of the high-level type of variables and the user-provided assertion n ≥ 1, we get the precondition I for the counter step procedure:

I = (0 ≤ init ≤ 1 ∧ 0 ≤ event ≤ 1 ∧ 0 ≤ reset ≤ 1 ∧ n ≥ 1)
We define the following system of fixpoint equations:

Q 1 = I Q 2 = (Q 1 (init = 1))[cnt := event] Q 3 = Q 1 (init = 0) Q 4 = (Q 3 (reset = 1))[cnt := event] Q 5 = (Q 3 (reset = 0 ∧ cnt < n))[cnt := cnt + event] Q 6 = Q 3 (cnt ≥ n) Q 7 = Q 4 Q 5 Q 6 Q 8 = Q 2 Q 7
Using a classical Linear Relation Analysis, we get the following result for Q 8 corresponding to the exit point of the counter step procedure:

Q 8 = (0 ≤ init ≤ 1 ∧ 0 ≤ reset ≤ 1 ∧ 0 ≤ event ≤ 1 ∧ n ≥ 1)
It is an utterly imprecise result, since we get nothing more than the precondition I itself. This not surprising, due to the convex hull operator applied for Q 7 and Q 8 , and more so since we did not take into account that the counter step procedure is called repeatedly inside an infinite loop, with the init variable being true at the first iteration and false everafter.

Thus it is interesting to compute a disjunctive relational summary of the counter step procedure, to obtain a more precise representation of its behavior, and in the meantime, to consider the specific nature of step procedures.

Disjunctive Summaries of Step Procedures

We are interested in computing summaries of reactive components implemented by a step procedure. Step procedures can be either generated automatically as a result of the compilation of a reactive program, such as for synchronous languages, or implemented externally in a host language such as C.

General Principle

Following the approach presented in Chapter 5, we compute the disjunctive relational summary of a step procedure p by iterative refinement of its global precondition I .

Intuition

Reactive components update the value of variables based on the previous value of memory variables and the current value of input variables. Thus it is interesting to compute the summary of a component by distinguishing behaviors according to preconditions on memory variables. Additionally, to obtain precise component summaries, we introduce an additional level of disjunction, by partitioning further according to preconditions on input variables. Partitioning with respect to constraints on memory variables is designed to separate behaviors according to high-level component states, whereas partitioning with respect to constraints on input variables separate the possible ways in which the next state and outputs are computed.

Two-Level Partition Refinement

We use a two-level partition refinement scheme for step procedures. First, we refine the global precondition I of a step procedure according to constraints on memory variables. This first refinement phase produces an abstract partition δ M = {I 1 , ..., I n } of the global precondition I . In a second phase, we refine each precondition I k ∈ δ M according to constraints on input variables. Finally, we obtain an abstract partition δ = {I 1,1 , .., I 1,m 1 , ..., I n,1 , .., I n,mn } of the global precondition I .

The abstract partition δ can be seen as made of two levels, in the sense that for each k = 1..n, the sets {I k,1 , .., I k,m k } ⊆ δ of preconditions produced by the second phase are themselves abstract partitions of a precondition I k ∈ δ M given by the first refinement phase.

Refinement Heuristics

Let I k be a precondition of a step procedure p. Let Q i (I k ) ∈ D be the abstract value discovered at a control location ν i of p by a relational analysis under the precondition I k . Definition 8.2.1 (Refinement with respect to memory variables). Let M 0 be the set of variables representing initial values of memory variables. If s is a complementable abstract value such that:

1. We should note that most step procedures in practice have no loops. Loops may appear in step procedures generated from synchronous languages like Lustre when array constructs are used.

Q i (I k ) ↓ M 0 s 2

Example

We compute a disjunctive relational summary over the convex polyhedra abstract domain for the counter step procedure shown in Figure 8.1. The counter step procedure is represented by a system of fixpoint equations:

I = (0 ≤ init ≤ 1 ∧ 0 ≤ event ≤ 1 ∧ 0 ≤ reset ≤ 1 ∧ n ≥ 1) Q 1 = I (cnt = cnt 0 ) Q 2 = (Q 1 (init = 1))[cnt := event] Q 3 = Q 1 (init = 0) Q 4 = (Q 3 (reset = 1))[cnt := event] Q 5 = (Q 3 (reset = 0 ∧ cnt < n))[cnt := cnt + event] Q 6 = Q 3 (cnt ≥ n) Q 7 = Q 4 Q 5 Q 6 Q 8 = Q 2 Q 7
We duplicate only the variable cnt with cnt 0 since it is the only parameter modified by the procedure. Let M 0 = {init, n, cnt 0 } be the set of variables representing initial values of memory variables. Refinement of I A Linear Relation Analysis of the system of fixpoint equations gives for Q 2 at program point 2:

Refinement According To Memory Variables

I I 1 I 1 I 2 I 2 init 0 = 1 init 0 = 0 cnt 0 < n cnt 0 ≥ n
Q 2 (I ) = (init = 1 ∧ cnt = event ∧ 0 ≤ cnt ≤ 1 ∧ 0 ≤ reset ≤ 1 ∧ n ≥ 1) Q 2 ↓ M 0 = (init = 1 ∧ n ≥ 0)
The inequality constraint s = (init ≥ 1) from Q 2 ↓ M 0 is a complementable abstract value. The complement of s with respect to I is s = (init ≤ 0) I = (init = 0). The global precondition I is refined into I 1 and I 1 :

I 1 = I s = (init = 1 ∧ 0 ≤ event ≤ 1 ∧ 0 ≤ reset ≤ 1 ∧ n ≥ 1) I 1 = I s = (init = 0 ∧ 0 ≤ event ≤ 1 ∧ 0 ≤ reset ≤ 1 ∧ n ≥ 1)
Refinement of I 1 A Linear Relation Analysis of the counter step procedure under the precondition I 1 gives at program point 4:

Q 4 (I 1 ) ↓ M 0 = (init = 0 ∧ n ≥ 1)
We gained no interesting property on memory variables, besides the constraints that we already had in I 1 . This was expected since the program point 4 is only guarded by the condition reset = 1 concerning only input variables. We get at program point 5:

Q 5 (I 1 ) = (init = 0 ∧ reset = 0 ∧ cnt = cnt 0 + event ∧ cnt 0 ≤ cnt ≤ cnt 0 + 1 ∧ n ≥ 1 ∧ cnt 0 < n) Q 5 (I 1 ) ↓ M 0 = (init = 0 ∧ cnt 0 < n ∧ n ≥ 1)
We can refine I 1 according to the constraint cnt 0 < n into I 2 and I 2 :

I 2 = (init = 0 ∧ cnt 0 < n ∧ 0 ≤ event ≤ 1 ∧ 0 ≤ reset ≤ 1 ∧ n ≥ 1) I 2 = (init = 0 ∧ cnt 0 ≥ n ∧ 0 ≤ event ≤ 1 ∧ 0 ≤ reset ≤ 1 ∧ n ≥ 1)
Both I 2 and I 2 can not be refined further according to memory variables. We get an abstract partition δ M = {I 1 , I 2 , I 2 } of the global precondition I :

I 1 = (init = 1 ∧ 0 ≤ event ≤ 1 ∧ 0 ≤ reset ≤ 1 ∧ n ≥ 1) I 2 = (init = 0 ∧ cnt 0 < n ∧ 0 ≤ event ≤ 1 ∧ 0 ≤ reset ≤ 1 ∧ n ≥ 1) I 2 = (init = 0 ∧ cnt 0 ≥ n ∧ 0 ≤ event ≤ 1 ∧ 0 ≤ reset ≤ 1 ∧ n ≥ 1)

Refinement According To Input Variables

We denote as X = {event, reset} the set of input variables of the bounded event counter.

In the second refinement phase, we refine each precondition obtained in δ M according to constraints on input variables. Refinement of I 2 A Linear Relation Analysis of the counter step procedure under the precondition I 2 gives at program point 4:

I I 1 I 1 I 2 I 3 I 3 I 2 I 4 I 4 init 0 = 1 init 0 = 0 cnt 0 < n cnt 0 ≥ n reset 0 = 1 reset 0 = 0 reset 0 = 1 reset 0 = 0
Q 4 (I 2 ) = (init = 0 ∧ cnt 0 < n ∧ reset = 1 ∧ cnt = event ∧ 0 ≤ cnt ≤ 1 ∧ n ≥ 1) Q 4 (I 2 ) ↓ {M 0 , X} = (init = 0 ∧ cnt 0 < n ∧ reset = 1 ∧ 0 ≤ event ≤ 1 ∧ n ≥ 1)
The precondition I 2 can be refined according to the constraint reset ≥ 1 in Q 4 (I 2 ) ↓ X and its complement reset = 0 into I 3 and I 3 :

I 3 = (init = 0 ∧ cnt 0 < n ∧ reset = 1 ∧ 0 ≤ event ≤ 1 ∧ n ≥ 1) I 3 = (init = 0 ∧ cnt 0 < n ∧ reset = 0 ∧ 0 ≤ event ≤ 1 ∧ n ≥ 1)
The preconditions I 3 and I 3 can not be refined any further.

Refinement of I 2 A Linear Relation Analysis of the procedure under I 2 gives:

Q 4 (I 2 ) = (init = 0 ∧ cnt 0 ≥ n ∧ reset = 1 ∧ cnt = event ∧ 0 ≤ cnt ≤ 1 ∧ n ≥ 1) Q 4 (I 2 ) ↓ {M 0 , X} = (init = 0 ∧ cnt 0 ≥ n ∧ reset = 1 ∧ 0 ≤ event ≤ 1)
As for I 2 , we can refine I 2 according to the constraint reset ≥ 0 into I 4 and I 4 :

I 4 = (init = 0 ∧ cnt 0 ≥ n ∧ reset = 1 ∧ 0 ≤ event ≤ 1 ∧ n ≥ 1) I 4 = (init = 0 ∧ cnt 0 ≥ n ∧ reset = 0 ∧ 0 ≤ event ≤ 1 ∧ n ≥ 1)

Abstract Partition of I

We get an abstract partition δ = {I 1 , I 3 , I 3 , I 4 , I 4 } of the global precondition I of the counter step procedure:

I 1 = (init = 1 ∧ 0 ≤ event ≤ 1 ∧ 0 ≤ reset ≤ 1 ∧ n ≥ 1) I 3 = (init = 0 ∧ cnt 0 < n ∧ reset = 1 ∧ 0 ≤ event ≤ 1 ∧ n ≥ 1) I 3 = (init = 0 ∧ cnt 0 < n ∧ reset = 0 ∧ 0 ≤ event ≤ 1 ∧ n ≥ 1) I 4 = (init = 0 ∧ cnt 0 ≥ n ∧ reset = 1 ∧ 0 ≤ event ≤ 1 ∧ n ≥ 1) I 4 = (init = 0 ∧ cnt 0 ≥ n ∧ reset = 0 ∧ 0 ≤ event ≤ 1 ∧ n ≥ 1)

Disjunctive Summary of the counter step Procedure

The disjunctive summary S c = {r 1 , r 2 , r 3 , r 4 , r 5 } of the counter step procedure is the collection of the abstract relations discovered at the exit of the procedure under each precondition in the abstract partition δ , with r 1 = Q 8 (I 1 ), r 2 = Q 8 (I 3 ), r 3 = Q 8 (I 3 ), r 4 = Q 8 (I 4 ), r 5 = Q 8 (I 4 ). The summary S c is as follows: Summary members derived from the same precondition on memory variables can be grouped into disjunctions r 2 ∨ r 3 and r 4 ∨ r 5 . The summary S c of the counter step procedure can be written as a set S c = {m 0 , m 1 , m 2 } of disjunctions of linear relations:

r 1 = (init = 1 ∧ cnt = event ∧ 0 ≤ cnt ≤ 1 ∧ 0 ≤ reset ≤ 1 ∧ n ≥ 1) r 2 = (init = 0 ∧ cnt 0 < n ∧ reset = 1 ∧ cnt = event ∧ 0 ≤ cnt ≤ 1 ∧ n ≥ 1) r 3 = (init = 0 ∧ cnt 0 < n ∧ reset = 0 ∧ cnt = cnt 0 + event ∧ cnt 0 ≤ cnt ≤ cnt 0 + 1 ∧ n ≥ 1) r 4 = (init = 0 ∧ cnt 0 ≥ n ∧ reset = 1 ∧ cnt = event ∧ 0 ≤ cnt ≤ 1 ∧ n ≥ 1) r 5 = (init = 0 ∧ cnt 0 ≥ n ∧ reset = 0 ∧ cnt = cnt 0 ∧ 0 ≤ event ≤ 1 ∧ n ≥ 1)

From Disjunctive Summaries To Modes

I I 1 r 1 I 1 I 2 I 3 r 2 I 3 r 3 I 2 I 4 r 4 I 4 r 5 m 1 m 2 m 0 cnt 0 < n cnt 0 ≥ n init 0 = 0 init 0 = 1 reset 0 = 1 reset 0 = 0 reset 0 = 1 reset 0 = 0
m 0 = (init = 1 ∧ cnt = event ∧ 0 ≤ cnt ≤ 1 ∧ 0 ≤ reset ≤ 1 ∧ n ≥ 1) m 1 = ((init = 0 ∧ cnt 0 < n ∧ reset = 1 ∧ cnt = event ∧ 0 ≤ cnt ≤ 1 ∧ n ≥ 1) ∨ (init = 0 ∧ cnt 0 < n ∧ reset = 0 ∧ cnt = cnt 0 + event ∧ cnt 0 ≤ cnt ≤ cnt 0 + 1 ∧ n ≥ 1)) m 2 = ((init = 0 ∧ cnt 0 ≥ n ∧ reset = 1 ∧ cnt = event ∧ 0 ≤ cnt ≤ 1 ∧ n ≥ 1) ∨ (init = 0 ∧ cnt 0 ≥ n ∧ reset = 0 ∧ cnt = cnt 0 ∧ 0 ≤ event ≤ 1 ∧ n ≥ 1))
The disjunctive summary of a step procedure becomes a set S = {m i } of disjunctions m i = T i,1 ∨ ... ∨ T i,n of linear relations (T i,k ) k=1..n ∈ D . Each disjunction m i is represented symbolically, without applying the convex hull operator. The summary members m i ∈ S can be seen as the modes of the reactive component.

We assume that there is a unique summary member m 0 ∈ S containing the constraint init 0 = 1 where m 0 (init = 1), that we identify as the initial mode of the component.

The sequence of reaction steps makes a component to transition from one mode to another. Thus a reactive component can be represented by a control structure made of modes, defined by disjunctions of abstract relations. These structures will be termed relational mode automata.

Relational Mode Automata

We propose a new representation of reactive components, allowing different levels of abstraction and designed specifically for the analysis of their behavior, called Relational Mode Automata (RMA).

Definitions

Let Σ be the set of values with Σ = Z∪B and B = {0, 1}. Given a finite set V of variables, a valuation of variables over V is a function σ : V → Σ. We denote as V(V ) the set of all variable valuations over V . The projection σ ↓ U of a valuation σ on U ⊆ V is defined as

σ ↓ U = {v → σ(v) | v ∈ U }.
Definition 8.3.1. (Relational Mode Automaton) A Relational Mode Automaton (RMA) is a tuple R = (X, Y, Z, M, I, Loc, 0 , φ, τ ) defined as follows:

• X, Y, Z, M are the finite disjoint sets of input variables, output variables, local variables and memory variables of the relational automaton R. We denote collectively as The values of variables are updated according to the binary relation φ( ) associated to each control location . Input variables and output variables are the external interface of a relational mode automaton. Relational Mode Automata can be seen as a relational extension of Mode-Automata [START_REF] Maraninchi | Mode-automata: A new domain-specific construct for the development of safe critical systems[END_REF].

V = X ∪ Y ∪ Z ∪ M the set of variables of R. • I ⊆ V(V ) is the set of initial variable valuations. • Loc is a finite set of control locations. • 0 ∈ Loc is the initial control location. • φ : Loc → Modes, with Modes = P(V(V ) × V(V )),

States

Quite classically, a state of a relational mode automaton is a pair ( , σ) made of a control location ∈ Loc and a variable valuation σ ∈ V(V ). We denote as S = Loc × V(V ) the set of states of a RMA. We will say that control resides at a given control location ∈ Loc for a state s if s is of the form s = ( , σ) for some variable valuation σ ∈ V(V ).

The set Loc of control locations should not be mistaken with the set S of automaton states, as control locations are only abstract places where control may reside during an execution. They are merely a notational facility to define the control structure of a relational mode automaton.

Domain of a Mode

The source src(φ( )) of a relation φ( ) defines the domain of applicability of a mode φ( ). The domain dom( ) ⊆ V(V ) of a mode φ( ) is defined as dom( ) = src(φ( )). When modes are known to be disjunctions of elements of a relational abstract domain D , such as disjunctions of linear relations, the domain of a mode is more specifically defined as: dom( ) =

T i ∈φ( ) src (T i )[V 0 /V ]

Control Transitions

Each pair ( j , i ) ∈ τ in the control transition relation represents a possible control change, from a location j to a location i , which is realized if the variable valuation σ of a state s = ( j , σ) satisfies the domain of the destination mode φ( i ), with σ ∈ dom( i ). Control transitions of the form ( , ) ∈ τ , when control can possibly stay at a given control location , are called self-transitions.

Example 8.3.1 (Bounded event counter). We define the relational mode automaton R ev = (X, Y, Z, M, I, Loc, 0 , φ, τ ) representing the bounded event counter implemented by the counter step procedure in Figure 8.1. The automaton R ev is shown in Figure 8.6. The variables of the automaton R ev are:

X = {event, reset} Y = {cnt} Z = ∅ M = {cnt, n}
The addition of an explicit init variable is not necessary, since relational mode automata have an explicit initial control location 0 . The set Loc of control locations is Loc = { 0 , 1 , 2 }. The modes of the relational mode automaton R ev are relations on variable valuations over V , given by the function φ : Loc → P(V(V ) × V(V )) defined formally as follows:

φ( 0 ) = (cnt = event ∧ 0 ≤ cnt ≤ 1 ∧ 0 ≤ reset ≤ 1 ∧ n ≥ 1) φ( 1 ) = ((cnt 0 < n ∧ reset = 1 ∧ cnt = event ∧ 0 ≤ cnt ≤ 1 ∧ n ≥ 1) ∨ (cnt 0 < n ∧ reset = 0 ∧ cnt = cnt 0 + event ∧ cnt 0 ≤ cnt ≤ cnt 0 + 1 ∧ n ≥ 1)) φ( 2 ) = ((cnt 0 ≥ n ∧ reset = 1 ∧ cnt = event ∧ 0 ≤ cnt ≤ 1 ∧ n ≥ 1) ∨ (cnt 0 ≥ n ∧ reset = 0 ∧ cnt = cnt 0 ∧ 0 ≤ event ≤ 1 ∧ n ≥ 1))
The set I of initial valuations is:

I = (cnt = 0 ∧ n ≥ 1 ∧ 0 ≤ event ≤ 1 ∧ 0 ≤ reset ≤ 1) σ 2 ↑ V = {[x → c, y → d, z → 3, t → 4] | c, d ∈ Σ} We should remark that the intersection (σ 1 ↑ V ) ∩ (σ 2 ↑ V ) is a singleton: (σ 1 ↑ V ) ∩ (σ 2 ↑ V ) = {[x → 1, y → 2, z → 3, t → 4]}
We define straightforwardly the lifting of extension to sets of variable valuations.

Definition 8.3.6 (Extension of sets of valuations). Let V k and V be finite sets of variables such that V k ⊆ V . We define the extension

U k ↑ V ⊆ V(V ) of U k ⊆ V(V k
) to a set of valuations over V as:

∀U k ⊆ V(V k ), U k ↑ V = σ k ∈U k σ k ↑ V
Using the extension of valuations, we define the extension of modes, which are relations over variable valuations. Definition 8.3.7 (Relational extension). Let V k and V be finite sets of variables such that V k ⊆ V . We define the extension ρ ↑

V ⊆ V(V ) × V(V ) of a relation ρ ⊆ V(V k ) × V(V k ) to a relation over valuations of V as: ∀ρ ⊆ V(V k ) 2 , ρ ↑ V = {(σ, σ ) ∈ V(V ) 2 | (σ k , σ k ) ∈ ρ ∧ σ ∈ σ k ↑ V ∧ σ ∈ σ k ↑ V } Example 8.3.3. Let V 1 = {x, y, n} and V 2 = {x, z, n} be sets of variables. Let V = V 1 ∪ V 2 . Let r 1 ⊆ V(V 1 ) × V(V 1 ) and r 2 ⊆ V(V 2 ) × V(V 2
) be two relations defined as:

r 1 = ((y = y 0 + 1 ∧ x < n) ∨ (y = y 0 ∧ x ≥ n)) r 2 = ((z = z 0 + 1 ∧ x < n) ∨ (z = z 0 ∧ x ≥ n))
The relations r 1 and r 2 can be seen as the modes of two relational mode automata R 1 and R 2 incrementing their own output variable, respectively y and z, when a common input variable x is strictly lower than n. The extensions to V of r 1 and r 2 are formally defined as:

r 1 ↑ V = {(σ, σ ) ∈ V(V ) × V(V ) | (σ (y) = σ(y) + 1 ∧ σ (x) < σ (n) ∧ σ (z) ∈ Σ ∧ σ ∈ V(V )) ∨ (σ (y) = σ(y) ∧ σ (x) ≥ σ (n) ∧ σ (z) ∈ Σ ∧ σ ∈ V(V ))} r 2 ↑ V = {(σ, σ ) ∈ V(V ) × V(V ) | (σ (z) = σ(z) + 1 ∧ σ (x) ≤ σ (n) ∧ σ (y) ∈ Σ ∧ σ ∈ V(V )) ∨ (σ (z) = σ(z) ∧ σ (x) ≥ σ (n) ∧ σ (y) ∈ Σ ∧ σ ∈ V(V ))} The intersection (r 1 ↑ V ) (r 2 ↑ V ) of the extended relations is: (r 1 ↑ V ) (r 2 ↑ V ) = ((y = y 0 + 1 ∧ z = z 0 + 1 ∧ x < n) ∨ (y = y 0 ∧ z = z 0 ∧ x ≥ n))
The intersection (r 1 ↑ V ) (r 2 ↑ V ) represents the parallel composition of the modes r 1 of R 1 and r 2 of R 2 .

Definition 8.3.8 (Parallel composition of RMA). Let R 1 = (X 1 , Y 1 , Z 1 , M 1 , I 1 , Loc 1 , 1 0 , φ 1 , τ 1 ) and R 2 = (X 2 , Y 2 , Z 2 , M 2 , I 2 , Loc 2 , 2 0 , φ 2 , τ 2 ) be relational mode automata. Let V = Vars(R 1 ) ∪ Vars(R 2 ). The parallel product R 1 × R 2 is the relational mode automaton (X, Y, Z, M 1 ∪ M 2 , I, Loc 1 × Loc 2 , ( 1 0 , 2 0 ), φ, τ ) where: • X = (X 1 \ Y 2 ) ∪ (X 2 \ Y 1 ) • Y = (Y 1 \ X 2 ) ∪ (Y 2 \ X 1 ) • Z = Z 1 ∪ Z 2 ∪ (X 1 ∩ Y 2 ) ∪ (Y 1 ∩ X 2 ) • I = (I 1 ↑ V ) ∩ (I 2 ↑ V ) • The function φ : Loc 1 × Loc 2 → P(V(V ) × V(V )
) associating modes to control locations is defined as:

∀ 1 ∈ Loc 1 , ∀ 2 ∈ Loc 2 , φ(( 1 , 2 )) = (φ 1 ( 1 ) ↑ V ) ∩ (φ 2 ( 2 ) ↑ V ) • (( 1 , 2 ), ( 1 , 2 )) ∈ τ ⇔ ( 1 , 1 ) ∈ τ 1 ∧ ( 2 , 2 ) ∈ τ 2
The parallel composition extends the modes of the original automata R 1 and R 2 to get modes updating the variables of both automata, defined over valuations of the global set V of variables.

The intersection (φ 1 ( 1 ) ↑ V ) ∩ (φ 2 ( 2 ) ↑ V ) of extended modes defines the parallel composition of each pair (φ 1 ( 1 ), φ 2 ( 2 )) of modes. It allows, in a simple way, the parallel composition of relational mode automata and the combination of the original modes.

In accordance with the semantics of synchronous languages, relational mode automata have simultaneously the control residing in their respective initial locations at the first reaction step.

(l 1 0 , l 2 0 ) (l 1 1 , l 2 1 ) (l 1 2 , l 2 2 ) (l 1 2 , l 2 1 ) (l 1 1 , l 2 2 ) Figure 8.7: Transition diagram of the product automaton R s = R 1 ev × R 2 ev .
Example 8.3.4 (Parallel composition of bounded counters). We consider the parallel composition of two relational mode automata R 1 and R 2 representing bounded event counters reacting to the same event and reset commands, where

R 1 = R ev [cnt/cnt 1 ] and R 2 = R ev [cnt/cnt 2 ]. We define the parallel product R s = R 1 × R 2 . The relational mode automaton R s = (X s , Y s , Z s , M s , I s , Loc 1 × Loc 2 , ( 1 0 , 2
0 ), φ s , τ s ) is defined as follows. The sets of

Reachability Analysis of Relational Mode Automata

We define a reachability analysis for relational mode automata which computes, for each control location ∈ Loc, approximations reach ( ) ∈ D of the sets of reachable valuations. The approximation reach ( ) is defined as the least solution of a system of fixpoint equations:

reach ( 0 ) = I ( j , 0 )∈τ post( j , 0 )(reach ( j )) dom( 0 ) ∀ i ∈ Loc, i = 0 ⇒ reach ( i ) = ( j , i )∈τ post( j , i )(reach ( j )) dom( i )

Computation Strategy

We compute a local increasing and decreasing sequence at each control location where there is a self-transition ( , ) ∈ τ , starting from the least upper bound of the abstract values computed at predecessor locations. Local sequences are computed inside a global sequence, until convergence of all abstract values associated to control locations. The computation of local sequences at each location is designed to avoid a loss of precision, by first computing the effect of a mode applied repeatedly in isolation, before the propagation to other modes.

Widening Limited by Preconditions of modes

The domain dom( ) of a mode φ( ) is an obvious invariant of the control location . The standard widening operator ∇ does not take into consideration dom( ) and does not preserve it in general. We use a widening ∇ : D × D → D limited by dom( ) in the local sequences at each control location . The limited widening ∇ is defined as:

Q 1 ∇ Q 2 = (Q 1 ∇Q 2 ) dom( )

Local Increasing Sequences

The local increasing sequence (Y i ) k≥0 at a control location , starting with an abstract value d ∈ D , is defined as:

Y 0 = d Y i+1 = Y i ∇ (Y i F (Y i ))
where the local transfer function F : D → D gives the image of an abstract value by the mode φ( ) as follows:

∀d ∈ D , F (d ) = post( , )(d ) dom( ) if ( , ) ∈ τ d if ( , ) / ∈ τ
We denote as Y ∇ the limit of a local increasing sequence (Y i ) i≥0 .

Computation Strategy

Let R 1 = (X 1 , Y 1 , Z 1 , M 1 , I 1 , Loc 1 , 1 0 , φ 1 , τ 1 ) and R 2 = (X 2 , Y 2 , Z 2 , M 2 , I 2 , Loc 2 , 2 0 , φ 2 , τ
2 ) be relational mode automata. The reduced product automaton of R 1 and R 2 is denoted as R = (X, Y, Z, M, I 1 I 2 , Loc 1 × Loc 2 , ( 1 0 , 2 0 ), φ, τ ). We adapt the reachability analysis defined in 8.4 to pairs of parallel relational mode automata. We compute local increasing and decreasing sequences at pairs ( 1 , 2 ) ∈ Loc 1 × Loc 2 of control locations inside a global sequence. At the beginning, only the initial pair ( 1 0 , 2 0 ) is known to be reachable. In each global iteration k ≥ 0, we explore only the pairs ( 1 , 2 ) of locations which were found to be reachable in earlier iterations.

We construct the control transition relation τ of the reduced product by adding the newly reachable pairs ( 1 , 2 ) at the end of each iteration. When the global sequence has converged, the reduced product automaton is only made of locations which have been found to be reachable during the analysis.

We denote as (G k ) k≥0 the global increasing sequence over the entire relational mode automaton. For each term G k , we denote as G Domain The domain dom(( 1 , 2 )) of a pair (φ( 1 ), φ( 2 )) of modes is defined as:

∀( 1 , 2 ) ∈ Loc 1 × Loc 2 , dom(( 1 , 2 )) = dom( 1 ) dom( 2 )
Limited Widening We define a widening operator ∇ ( 1 , 2 ) : D × D → D limited by dom(( 1 , 2 )) for each pair ( 1 , 2 ) of locations, as:

∀P, Q ∈ D , P ∇ ( 1 , 2 ) Q = (P ∇Q) dom(( 1 , 2 ))
Post-Condition Operator The post(( 1 , 2 )) : D → D operator giving the image of an abstract value d by a pair (φ( 1 ), φ( 2 )) of modes is defined as:

∀d ∈ D , post(( 1 , 2 ))(d ) = post( 1 )(d ) post( 2 )(d )
Control Transition Relation The control transition relation (τ k ) k≥0 of the reduced product automaton at an iteration k of the global increasing sequence (G k ) k≥0 is:

τ 0 = ∅ τ k+1 = {(( 1 , 2 ), ( 1 , 2 )) | ( 1 , 2 ) = ( 1 0 , 2 0 ) ∧ post(( 1 , 2 ), ( 1 , 2 ))(G ( 1 , 2 ) k ) dom(( 1 , 2 )) = ⊥}

Local Increasing Sequence

A local increasing sequence (Y i ) i≥0 at a pair ( 1 , 2 ) of locations starting with an abstract value d ∈ D is defined as:

Y ( 1 , 2 ) 0 = d Y ( 1 , 2 ) i+1 = Y ( 1 , 2 ) i ∇ ( 1 , 2 ) (Y ( 1 , 2 ) i F ( 1 , 2 ) (Y ( 1 , 2 ) i ) Chapter 8
Modular Analysis of Reactive Systems as:

R 1 , 2 R ⇔ R = (X, Y, Z, M, I, Loc , 0 , φ , τ ) ∧ Loc = (Loc \ { 1 , 2 }) ∪ { } ∧ / ∈ Loc ∧ 0 = if ( 1 = 0 ) ∨ ( 2 = 0 ) 0 otherwise ∧ φ ( ) = φ( 1 ) ∪ φ( 2 ) ∧ ∀ = , φ ( ) = φ( ) ∧ τ = (τ ∩ (Loc × Loc )) ∪ {( , ) | ( , 1 ) ∈ τ ∨ ( , 2 ) ∈ τ } ∪ {( , ) | ( 1 , ) ∈ τ ∨ ( 2 , ) ∈ τ }
When modes φ( 1 ), φ( 2 ) are disjunctions of elements of a relational abstract domain D , the merged mode is φ ( ) = merge(φ( 1 ), φ( 2)) where merge : P(D ) × P(D ) → P(D ) can be any sound merging function such that:

T 1 ∈ φ( 1 ) T 2 ∈ φ( 2 ) γ(T 1 ) ∪ γ(T 2 ) ⊆ m∈merge(φ( 1 ),φ( 2 )) γ(m)
In particular, merge can keep separated the disjuncts of both modes such that:

merge(φ( 1 ), φ( 2 )) = φ( 1 ) ∨ φ( 2 )
or in another extreme, be the join of all disjuncts:

merge(φ( 1 ), φ( 2 )) = T i ∈φ( 1 )∪φ( 2 )
T i

Internal Reduction

When the modes of a relational mode automaton are disjunctive relations, the precision of modes can be reduced by merging some disjuncts. For example, we can replace some disjuncts, or all of them, by their least upper bound. More generally, a mode φ( ) = T 1 ∨ ... ∨ T n is reduced into a mode φ ( ) with respect to a mode-reducing function mred : P(D ) → P(D ) as:

φ ( ) = mred(φ( ))
where mred can be any sound mode-reducing function, satisfying:

T i ∈φ( ) γ(T i ) ⊆ m i ∈mred(φ( )) γ(m i ) 8
reach ( 0 ) = (cnt = 0 ∧ 0 ≤ event ≤ 1 ∧ 0 ≤ reset ≤ 1 ∧ n ≥ 1) reach ( 1 ) = (cnt < n ∧ cnt + reset ≥ event ∧ cnt ≥ 0 ∧ 0 ≤ event ≤ 1 ∧ 0 ≤ reset ≤ 1) reach ( 2 ) = (cnt = n ∧ cnt ≥ 1 ∧ event ≥ reset ∧ reset ≥ 0 ∧ event ≤ 1)
The invariant of R ev is:

inv(R ev ) = reach ( 0 ) reach ( 1 ) reach ( 2 ) = (0 ≤ cnt ≤ n ∧ cnt + reset ≤ event + n ∧ 0 ≤ reset ≤ 1 ∧ event ≥ 0 ∧ n ≥ 1)

Weaker invariants

We can get a weaker and less-precise invariant of R by eliminating variables. The choice of variables to eliminate is made heuristically, according to a proof objective or high-level user-specified goals.

Example 8.7.2. If we are only interested in the bounds on the output variable cnt of the event counter, in terms of the counter capacity parameter n, we can use instead a weaker invariant W ev :

W ev = inv(R ev ) ↓ {cnt, n} = (0 ≤ cnt ≤ n ∧ n ≥ 1)
The weaker invariant W ev has fewer constraints than inv(R ev ) although it is still useful to prove that the variables of a collection of counter components are bounded. However, W ev is not expressive enough to discover the equality of parallel event counters reacting to the same event, such as in 8.5.3.

Disjunctive Invariant

Conversely, we can get a more precise invariant of a relational mode automaton by keeping as separate disjuncts some or all the abstract values reach ( ) discovered at each control location.

Example 8.7.3. For the bounded event counter, we can either keep the full disjunctive invariant:

J ev = reach ( 0 ) ∨ reach ( 1 ) ∨ reach ( 2 ) = (cnt = 0 ∧ 0 ≤ event ≤ 1 ∧ 0 ≤ reset ≤ 1 ∧ n ≥ 1) ∨ (cnt < n ∧ cnt + reset ≥ event ∧ cnt ≥ 0 ∧ 0 ≤ event ≤ 1 ∧ 0 ≤ reset ≤ 1) ∨ (cnt = n ∧ cnt ≥ 1 ∧ event ≥ reset ∧ reset ≥ 0 ∧ event ≤ 1)
or just distinguish the abstract value reach ( 0 ) discovered at the initial location from the other disjuncts:

J ev = reach ( 0 ) ∨ (reach ( 1 ) reach ( 2 )) = (cnt = 0 ∧ 0 ≤ event ≤ 1 ∧ 0 ≤ reset ≤ 1 ∧ n ≥ 1) ∨ (0 ≤ cnt ≤ n ∧ cnt + reset ≤ event + n ∧ 0 ≤ reset ≤ 1 ∧ event ≥ 0 ∧ n ≥ 1)
A disjunctive invariant of the relational mode automaton representing a given reactive component can be used to compute the abstract effect of a call to the step procedure of the component, when the component is instantiated inside a larger component. The abstract effect of a call to the step procedure is computed as for disjunctive summaries in 5.2.4. An example using disjunctive invariants is given in Chapter 9.

Relational Augmentation

An invariant J ∈ P(D ) of a relational mode automaton R can be augmented by adding back into J some constraints from the modes of R, describing how the values of memory variables are computed in terms of their previous values and input variables. It is intended as a way to reintroduce some of the relational information given in the modes of R, by combining it with the constraints discovered in the invariant J .

We compute an abstract relation Φ ∈ D on memory and input variables from the modes of R as follows:

Φ = ∈Loc   T i ∈φ( ) T i ↓ {M, X}   The augmented invariant Q R ∈ P(D ) is defined as: Q R = Q i ∈J Q i Φ

Conclusion

We proposed a new representation of the behavior of reactive components called Relational Mode Automata (RMA). Relational mode automata can be constructed automatically from a disjunctive summary of the step procedure of a reactive component. They are designed specifically for the analysis of reactive programs, allowing different levels of abstraction and precision.

We described a reachability analysis of RMA, which is able to analyze the parallel composition of several reactive components without requiring an explicit construction of the synchronous product of automata prior to the analysis. Instead, only the part of the composition found to be reachable during the analysis is explored and constructed.

We shown that the analysis results of a RMA representing a given reactive component can be used in the form of a disjunctive invariant to compute the effect of a call to the step procedure implementing the component, in order to analyze larger components. Thus our approach can be used for the modular analysis of reactive programs.

Our approach has been implemented for small examples using the PyApron library providing high-level Python bindings for convex polyhedra to the Apron library. In the next chapter, we present an application to a larger example which is a simplification of a real proposal of subway control system.

Chapter 9 Example: A Subway Control System

We are interested in the analysis of a larger reactive program which models the behavior of a subway control system. This is a classical example [START_REF] Halbwachs | Verification of real-time systems using linear relation analysis[END_REF] for the verification of synchronous programs which has been greatly simplified from a real proposition. The control system of a simple subway train is implemented by the train step procedure shown in Figure 9.1.

In our subway system, all trains on the same track receive a common time signal from a central clock, represented in each train by a boolean input variable s. Signaling beacons are installed along the tracks. The boolean input variable b is true when a beacon is detected by a train. Ideally, a train should cross one beacon per s signal. A train is controlled according to the difference delta between the number of received clock ticks and the number of detected beacons. A train is considered to be late when the difference delta becomes greater or equal to 10 and to be early when delta becomes lower or equal to -10.

We assume that trains have a stopping distance equal to 10 beacons. Trains are controlled using an hysteresis to avoid shaking for passenger comfort. A train begins to brake when delta = -10 and keeps braking until the train is completely stopped or delta ≥ 0. A train stays stopped until delta ≥ 0. Similarly, a train is considered to be late when delta = 10, and becomes ontime only when it has gained enough advance, which is when delta ≥ 0.

When a train is stopped, no new beacons are detected. When a train is late, in order to avoid collisions with other trains on the same track, the central clock disables the time signal for the track. In other trains, it causes delta to decrease, compelling trains to brake when delta becomes lower or equal to -10. When the slower train resumes its course and returns to its normal pace, more beacons are encountered and the difference delta starts to decrease. The train becomes on time again when delta becomes lower or equal to zero. The central clock then resumes the time signal for the entire track, allowing other trains to return to their normal speed. Thus collision avoidance is achieved by suspending time.

In order to guarantee the safety of the subway, we want to discover bounds on the difference nb 1 -nb 2 = delta2 -delta1 in number of encountered beacons between any pair of trains. These bounds can then be used for the initial placement of trains to ensure the absence of collisions. We also want to prove that numerical variables in each train are bounded at all times, to guarantee the absence of arithmetic overflows at runtime.

We start by analyzing a single train as implemented by the train step procedure.

Then, we show that the invariant discovered for a single train can be used in a modular way to prove the absence of collisions in a subway system made of several trains.

Detailed Summary of the train step Procedure

We construct a relational mode automaton representing a single train by computing the disjunctive relational summary of the train step procedure. The train step procedure is represented by the following system of fixpoint equations:

I = (0 ≤ init ≤ 1 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ b ≤ 1 ∧ 0 ≤ ontime ≤ 1 ∧ 0 ≤ late ≤ 1 ∧ 0 ≤ onbrake ≤ 1 ∧ 0 ≤ stopped ≤ 1) Q 1 = I (init 0 = init ∧ ontime 0 = ontime ∧ late 0 = late ∧ onbrake 0 = onbrake ∧ stopped 0 = stopped ∧ nbrake 0 = nbrake ∧ delta 0 = delta) Q 2 = (Q 1 (init = 1))[init := 0][delta := 0][ontime := 1][late := 0] [onbrake := 0][stopped := 0][nbrake := 0] Q 3 = (Q 1 (init = 0 ∧ ontime = 1))[delta := delta + s -b] Q 4 = (Q 3 (delta ≥ 10))[ontime := 0][late := 1][nbrake := 0] Q 5 = (Q 3 (delta ≤ -10))[ontime := 0][onbrake := 1][nbrake := b] Q 6 = (Q 3 (-9 ≤ delta ≤ 9))[nbrake := 0] Q 7 = Q 4 Q 5 Q 6 Q 8 = ((Q 1 (init = 0 ∧ ontime = 0 ∧ late = 1)) (s = 0))[delta := delta -b] [nbrake := 0] Q 9 = (Q 8 (delta ≤ 0))[ontime := 1][late := 0] Q 10 = (Q 8 (delta ≥ 1)) Q 9 Q 11 = (Q 1 (init = 0 ∧ ontime = 0 ∧ late = 0 ∧ onbrake = 1))[delta := delta + s -b] Q 12 = (Q 11 (delta ≥ 0))[ontime := 1][onbrake := 0][nbrake := 0] Q 13 = (Q 11 (delta ≤ -1 ∧ nbrake ≥ 10))[stopped := 1][onbrake := 0] Q 14 = (Q 11 (delta ≤ -1 ∧ nbrake ≤ 9))[nbrake := nbrake + b] Q 15 = Q 12 Q 13 Q 14 Q 16 = ((Q 1 (init = 0 ∧ ontime = 0 ∧ late = 0 ∧ onbrake = 0 ∧ stopped = 1)) (b = 0)) [delta := delta + s] Q 17 = (Q 16 (delta ≥ 0))[ontime := 1][stopped := 0][nbrake := 0] Q 18 = (Q 16 (delta ≤ -1)) Q 17 Q 19 = Q 1 (init = 0 ∧ ontime = 0 ∧ late = 0 ∧ onbrake = 0 ∧ stopped = 0) Q 20 = Q 2 Q 7 Q 15 Q 18 Q 19
The disjunctive summary of the train step procedure is computed according to the two-level refinement scheme presented in 8.2. The global precondition I of the procedure is first refined according to preconditions on memory variables and then according to preconditions on input variables. The sets of input, output, local and memory variables of a train component are: X = {s, b} Y = {ontime, late, onbrake, stopped, delta} Z = ∅ M = {init, ontime, late, onbrake, stopped, delta, nbrake} We denote as M 0 = {init 0 , delta 0 , nbrake 0 , ontime 0 , late 0 , onbrake 0 , stopped 0 } the set of variables representing previous values of memory variables.

Refinement on Memory Variables

Q 2 = (init 0 = 1 ∧ 0 ≤ ontime 0 ≤ 1 ∧ 0 ≤ late 0 ≤ 1 ∧ 0 ≤ onbrake 0 ≤ 1 ∧ 0 ≤ stopped 0 ≤ 1 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ b ≤ 1 ∧ init = 0 ∧ delta = 0 ∧ ontime = 1 ∧ late = 0 ∧ onbrake = 0 ∧ stopped = 0 ∧ nbrake = 0) Q 2 ↓ M 0 = (init 0 = 1 ∧ 0 ≤ ontime 0 ≤ 1 ∧ 0 ≤ late 0 ≤ 1 ∧ 0 ≤ onbrake 0 ≤ 1 ∧ 0 ≤ stopped 0 ≤ 1)
I can be refined according to the constraint init 0 = 1 and its complement init 0 = 0 into two new preconditions I 1 and I 1 :

I 1 = I (init 0 = 1) = (init 0 = 1 ∧ 0 ≤ ontime 0 ≤ 1 ∧ 0 ≤ late 0 ≤ 1 ∧ 0 ≤ onbrake 0 ≤ 1 ∧ 0 ≤ stopped 0 ≤ 1 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ b ≤ 1) I 1 = I (init 0 = 0) = (init 0 = 0 ∧ 0 ≤ ontime 0 ≤ 1 ∧ 0 ≤ late 0 ≤ 1 ∧ 0 ≤ onbrake 0 ≤ 1 ∧ 0 ≤ stopped 0 ≤ 1 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ b ≤ 1)
Refinement of I 1 We compute a Linear Relation Analysis of the train step procedure under the precondition I 1 . We get

Q 3 (I 1 ) = ⊥, Q 8 (I 1 ) = ⊥, Q 11 (I 1 ) = ⊥, Q 16 (I 1 ) = ⊥ and Q 19 (I 2 ) = ⊥.
The precondition I 1 can not be refined further.

Refinement of I 1 We compute a Linear Relation Analysis under the precondition I 1 . We can refine I 1 at program point 3, according to the constraint ontime 0 = 1 and its complement ontime 0 = 0 into I 2 and I 2 : Refinement of I 2 We can refine I 2 at program point 8 according to the constraint late 0 = 1 and its complement late 0 = 0 into I 3 and I 3 :

I 2 = I 1 (ontime 0 = 1) = (init 0 = 0 ∧ ontime 0 = 1 ∧ 0 ≤ late 0 ≤ 1 ∧ 0 ≤ onbrake 0 ≤ 1 ∧ 0 ≤ stopped 0 ≤ 1 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ b ≤ 1) I 2 = I 1 (ontime 0 = 0) = (init 0 = 0 ∧ ontime 0 = 0 ∧ 0 ≤ late 0 ≤ 1 ∧ 0 ≤ onbrake 0 ≤ 1 ∧ 0 ≤ stopped 0 ≤ 1 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ b ≤ 1)

Refinement

I 3 = I 2 (late 0 = 1) = (init 0 = 0 ∧ ontime 0 = 0 ∧ late 0 = 1 ∧ 0 ≤ onbrake 0 ≤ 1 ∧ 0 ≤ stopped 0 ≤ 1 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ b ≤ 1) I 3 = I 2 (late 0 = 0) = (init 0 = 0 ∧ ontime 0 = 0 ∧ late 0 = 0 ∧ 0 ≤ onbrake 0 ≤ 1 ∧ 0 ≤ stopped 0 ≤ 1 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ b ≤ 1)
Refinement of I 3 Under precondition I 3 , we get Q 11 (I 3 ) = ⊥, Q 16 (I 3 ) = ⊥ and Q 19 (I 3 ) = ⊥. We do not consider the program point 9 as it is guarded by the test *delta <= 0 and the current value of delta is computed by the statement *delta = *delta -b which depends on the input variable b. Thus I 3 can not be refined according to memory variables.

Refinement of I 3 We can refine I 3 at program point 11 according to the constraint onbrake 0 = 1 and its complement onbrake 0 = 0 into I 4 and I 4 :

I 4 = I 3 (onbrake 0 = 1) = (init 0 = 0 ∧ ontime 0 = 0 ∧ late 0 = 1 ∧ onbrake 0 = 1 ∧ 0 ≤ stopped 0 ≤ 1 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ b ≤ 1) I 4 = I 3 (onbrake 0 = 0) = (init 0 = 0 ∧ ontime 0 = 0 ∧ late 0 = 0 ∧ onbrake 0 = 0 ∧ 0 ≤ stopped 0 ≤ 1 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ b ≤ 1)
Refinement of I 4 Under precondition I 4 , we get Q 16 (I 4 ) = ⊥ and Q 19 (I 4 ) = ⊥. Tests at program points 12, 13 and 14 depends on input variables. The else if(*nbrake >= 10) branch is entered if delta ≤ -1 and Q 13 is defined in the system of equations as being guarded by the condition delta ≤ -1 ∧ nbrake ≥ 10. Thus I 4 can not be refined according to memory variables only.

Refinement of I 4 We can refine I 4 at program point 16 according to the constraint stopped 0 = 1 and its complement stopped 0 = 0 into I 5 and I 5 : ∧ ontime 0 = 0 ∧ onbrake 0 = 0 ∧ onbrake = 0 ∧ nbrake = 0 ∧ late 0 = 0 ∧ late = 0 ∧ init = 0 ∧ b = 0 ∧ delta 0 + 1 ≥ delta ∧ delta ≥ delta 0 ∧ delta ≥ 0) r 11 = (init 0 = 0 ∧ stopped 0 = 1 ∧ stopped = 1 ∧ nbrake = nbrake 0 ∧ delta = delta 0 + s ∧ ontime 0 = 0 ∧ ontime = 0 ∧ onbrake 0 = 0 ∧ onbrake = 0 ∧ late 0 = 0 ∧ late = 0 ∧ init = 0 ∧ b = 0 ∧ delta ≤ -1 ∧ delta 0 + 1 ≥ delta ∧ delta ≥ delta 0 ) r 12 = (init 0 = 0 ∧ ontime 0 = 0 ∧ late 0 = 0 ∧ onbrake 0 = 0 ∧ stopped 0 = 0 ∧ delta = delta 0 ∧ nbrake = nbrake 0 ∧ stopped = stopped 0 ∧ ontime = ontime 0 ∧ onbrake = onbrake 0 ∧ late

I 5 = I 4 (stopped 0 = 1) = (init 0 = 0 ∧ ontime 0 = 0 ∧ late 0 = 1 ∧ onbrake 0 = 1 ∧ stopped 0 = 1 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ b ≤ 1) I 5 = I 4 (stopped 0 = 0) = (init 0 = 0 ∧ ontime 0 = 0 ∧ late 0 = 0 ∧ onbrake 0 = 0 ∧ stopped 0 = 0 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ b ≤ 1)

Refinement

= late 0 ∧ init = 0 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ b ≤ 1)
The members of the disjunctive summary S train can be grouped into modes according to which precondition on memory variables they have been derived from, as shown in From the modes of a train given by the summary of the train step procedure, we construct the relational mode automaton R train = (X, Y, Z, M, I, Loc, init , φ, τ ) shown in Figure 9.9. The initial variable valuations are:

I = (0 ≤ s ≤ 1 ∧ 0 ≤ b ≤ 1 ∧ 0 ≤ ontime ≤ 1 ∧ 0 ≤ late ≤ 1 ∧ 0 ≤ onbrake ≤ 1 ∧ 0 ≤ stopped ≤ 1 ∧ init = 1)
The set of control locations is Loc = { init , ontime , late , onbrake , stopped } and the modes are φ( init ) = m 0 , φ( ontime ) = m 1 , φ( late ) = m 2 , φ( onbrake ) = m 3 , φ( stopped ) = m 4 . We can write each mode φ( ) as a conjunction A ∧ T of a precondition A and a disjunction T = T , 0 ∨...∨T , n of linear input-output relations (T i ) i=1..n . The precondition A gives the domain of the mode and the disjunction T gives the possible ways in which the variables can be updated. The function φ : Loc → V(V ) × V(V ) associating modes to control locations is: ∧ stopped = stopped 0 ∧ onbrake = onbrake 0 ∧ nbrake = 0))

φ( init ) = (delta = 0 ∧ late = 0 ∧ stopped = 0 ∧ onbrake = 0 ∧ nbrake = 0 ∧ ontime = 1 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ b ≤ 1) φ( ontime ) = (ontime 0 = 1 ∧ 0 ≤ late 0 ≤ 1 ∧ 0 ≤ stopped 0 ≤ 1 ∧ 0 ≤ onbrake 0 ≤ 1 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ b ≤
The control transition relation τ ⊆ Loc × V(V ) × Loc is: τ = {( init , , ontime ), ( ontime , , ontime ), ( ontime , , late ), ( ontime , , onbrake ), ( late , , late ), ( late , , ontime ), ( onbrake , , onbrake ), ( onbrake , , ontime ), ( onbrake , , stopped ), ( stopped , , stopped ), ( stopped , , ontime )}

Analysis of a Single Train

For each control location = init , we denote as stay a property which is satisfied when control stays at :

stay ontime = (-9 ≤ delta ≤ 9) stay late = (delta ≥ 1) stay onbrake = (delta ≤ -1 ∧ nbrake ≤ 10) stay stopped = (delta ≤ -1 ∧ nbrake ≥ 10)

We define a limited widening operator ∇ for each control location as: P ∇ Q = (P ∇Q) stay Initially, only the control location init is known to be reachable. The initial term of the global increasing sequence is trivially:

G init = I = (0 ≤ s ≤ 1 ∧ 0 ≤ b ≤ 1 ∧ 0 ≤ ontime ≤ 1 ∧ 0 ≤ late ≤ 1 ∧ 0 ≤ onbrake ≤ 1 ∧ 0 ≤ stopped ≤ 1)

Analysis of a Single Train

The incoming abstract value in ontime at ontime is:

in ontime = post( init , ontime )(G init ) = (ontime = 1 ∧ stopped = 0 ∧ onbrake = 0 ∧ nbrake = 0 ∧ late = 0

∧ delta = 0 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ b ≤ 1)
The abstract value G ontime is the limit of a local increasing and decreasing sequence at ontime starting with in ontime .

Local iteration at ontime

We compute a local increasing sequence at ontime as follows: After convergence, we get:

G ontime = (ontime = 1 ∧ stopped = 0 ∧ onbrake = 0 ∧ nbrake = 0 ∧ late = 0 ∧ -9 ≤ delta ≤ 9 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ b ≤ 1)

Local iteration at onbrake

The incoming abstract value at onbrake is:

in onbrake = post( ontime , onbrake )(G ontime ) = (onbrake = 1 ∧ stopped = 0 ∧ ontime = 0 ∧ nbrake = 1 ∧ late = 0 ∧ delta = -10 ∧ s = 0 ∧ b = 1)

We compute a local increasing sequence at onbrake , we get:

G onbrake = (onbrake = 1 ∧ stopped = 0 ∧ ontime = 0 ∧ late = 0 ∧ b ≤ 1 ∧ nbrake ≥ b + s ∧ delta ≤ -1 ∧ nbrake ≤ 10 ∧ s ≥ 0 ∧ nbrake ≥ 1 ∧ delta + nbrake ≥ s -9)

Local iteration at stopped

The incoming abstract value at stopped is: Let J train be a disjunctive invariant of the R train automaton defined as:

J train = post( init , ontime )(G init ) ∨ (G ontime G onbrake G stopped G late )
For clarity, we use a simpler and weaker disjunctive invariant J train of R train :

J train = (init = 0 ∧ delta = 0 ∧ late = 0) ∨ (init = 0 ∧ -19 ≤ delta ≤ 10 ∧ late = 0)

In order to increase moderately the precision, we augment J train by adding relations given by the modes of the automaton R train as described in 8.7.4.

Q train = (init 0 = 1 ∧ init = 0 ∧ delta = 0 ∧ late = 0) ∨ (init 0 = 0 ∧ init = 0 ∧ -19 ≤ delta ≤ 10 ∧ delta = delta 0 + s -b ∧ 0 ≤ late ≤ 1)
Q train is an over-approximation of a reaction step of the relational mode automaton R train and represents the effect of a call to the train step procedure.

Modular Analysis of a Pair of Trains

We want to discover a bound on the difference delta = nb 2 -nb 1 in number of encountered beacons on a subway track between any pair of trains. A subway track with two trains is modeled by the track step procedure given in Figure 9.10. As we did previously for a single train, we also want to prove that the variables of all trains are bounded. We analyze the track step procedure in a modular way, using the results of the analysis of a single train. The track step procedure implements an instance of each train by calling the train step procedure which updates the trains variables at each reaction step. Since the track step procedure is written only for analysis purposes, the numbers of detected beacons are counted in an unbounded fashion and stored respectively in nb 1 and nb 2 .

Disjunctive Summary of track step

The disjunctive summary S track = {r 1 , r 2 } of the track step procedure is:

A = (0 ≤ b1 ≤ 1 ∧ 0 ≤ b2 ≤ 1 ∧ 0 ≤ clk ≤ 1 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ ontime1 ≤ 1 ∧ 0 ≤ late1 ≤ 1 ∧ 0 ≤ onbrake1 ≤ 1 ∧ 0 ≤ stopped1 ≤ 1 ∧ 0 ≤ ontime2 ≤ 1 ∧ 0 ≤ late2 ≤ 1 ∧ 0 ≤ onbrake2 ≤ 1 ∧ 0 ≤ stopped2 ≤ 1 ∧ 0 ≤ init ≤ 1 ∧ 0 ≤ init 0 ≤ 1 ∧ 0 ≤ late1 0 ≤ 1 ∧ 0 ≤ late2 0 ≤ 1) r 1 = A (init 0 = 1 ∧ init = 0 ∧ nb1 = 0 ∧ nb2 = 0 ∧ s = clk ∧ delta1 = 0 ∧ delta2 = 0 ∧ late1 = 0 ∧ late2 = 0) r 2 = A (init 0 = 0 ∧ init = 0 ∧ nb1 = nb1 0 + b1 ∧ nb2 = nb2 0 + b2 ∧ delta1 = delta1 0 + s -b1 ∧ delta2 = delta2 0 + s -b2 ∧ late1 0 + late2 0 + s ≥ clk ∧ late1 0 + s ≤ 1 ∧ late2 0 + s ≤ 1 ∧ clk ≥ s)

Conclusion

In this chapter, we were interested in the analysis of a classical example [START_REF] Halbwachs | Verification of real-time systems using linear relation analysis[END_REF] of subway system inspired from a real industrial proposition. We presented the detailed computation of the disjunctive relational summary of the metro step procedure implementing a single train. The computed summary was used to construct automatically an abstraction of the behavior of a single train as a relational mode automaton. We analyzed the relational mode automaton representing a single train and discovered that all the variables of a train are bounded at runtime. In particular, we found using our approach the classical result that the difference delta between the number of received clock ticks and the number of detected beacons is always bounded with -19 ≤ delta ≤ 10. We computed a disjunctive relational invariant of an individual train from analysis results.

We used the disjunctive relational invariant of a single train to analyze a pair of trains on a subway track in a modular way. Reduction techniques presented in 8.6 were used to simplify the analysis and get rid of unnecessary details. We discovered that the difference nb 1 -nb 2 = delta 2 -delta 1 in number of encountered beacons between any pair of trains on a track is always bounded with -29 ≤ nb 1 -nb 2 ≤ 29 although neither 29 nor bounds are given explicitly.

The computations involved in this example have been performed using the PyApron library which provides a high-level Python binding to the Apron library for the convex polyhedra implementation. The implementation of the refinement process was written specifically for that example.

We chose to consider all variables as integers and to represent booleans as integer variables between 0 and 1. We could have used an abstract domain allowing the expression of boolean properties with convex polyhedra [START_REF] Jeannet | Partitionnement dynamique dans l'analyse de relations linéaires et application à la vérification de programmes synchrones[END_REF][START_REF] Bakhirkin | Extending constraint-only representation of polyhedra with boolean constraints[END_REF].

Chapter 10 Conclusion

We proposed a modular interprocedural analysis for numerical properties, as a solution to the cost of using expressive relational abstract domains in program analysis. An analysis using a relational abstract domain can be straightforwardly converted into a relational analysis computing an input-output relation. Such relations can be used as procedure summaries, computed once and for all, and used in a bottom-up fashion to compute the effect of procedure calls.

We described a general framework to compute relational procedure summaries by abstract interpretation, based on the forward propagation of abstract input-output relations. Even if it is especially applied to convex polyhedra, it can be used with any relational abstract domain. Although the idea is not new [START_REF] Irigoin | Semantical interprocedural parallelization: An overview of the PIPS project[END_REF], we proposed a formalization of relational abstract interpretation that we did not find elsewhere.

Applying this idea to Linear Relation Analysis, we concluded that procedure summaries made of individual input-output relations represented by convex polyhedra are not precise enough and deserve to be refined disjunctively. We proposed a method based on precondition partitioning to compute disjunctive relational summaries. We gave partitioning heuristics for refining summaries, according to the reachability of control points or calling contexts of called procedures. We also identified several improvements to summary computation itself, like widening limited by preconditions and previously computed relations, and a more precise computation of abstract relations at loops exit points.

We shown that our approach can be used to compute disjunctive relational summaries of recursive procedures, as it is often a weakness of existing interprocedural analyses. Our analysis was able to uncover non-trivial procedure behaviors caused by recursion.

We provide an implementation of our approach in a new static analysis platform for C programs called mars. It was the product of a significant effort to design a new tool to simplify the development of static analyses, while accepting a large subset of C and providing highly-precise traceability information. Using mars, we conducted experiments of our modular analysis on a set of benchmark programs well-known in the WCET research community. We shown that our approach can significantly reduce the analysis time for Linear Relation Analysis, compared to a classical full context-sensitive approach where procedures are analyzed completely in each call context. This is especially the case for procedures which are called several times, like procedures which are part of a library or a framework. On the other hand, analysis precision is not significantly damaged and can be even improved due to the use of disjunction. This approach was published in [START_REF] Boutonnet | Disjunctive relational abstract interpretation for interprocedural program analysis[END_REF]. Some possible future works were given in 6.6.

During the time of this thesis, we also published the continuation of earlier works on the improvement [START_REF] Boutonnet | Improving the results of program analysis by abstract interpretation beyond the decreasing sequence[END_REF] of Linear Relation Analysis and the application of Linear Relation Analysis to the computation of the Worst-Case Execution Time of programs [START_REF] Raymond | Improving WCET evaluation using linear relation analysis[END_REF].

Reactive systems can be generally structured as collections of components reacting to inputs, producing outputs and updating their internal memories to achieve the system functionality. The reaction of each component to its environment is implemented by a step procedure. Synchronous languages like Lustre are well-known for the implementation of synchronous reactive systems.

In a second part, we proposed an approach toward a modular analysis of reactive systems for numerical properties. We presented a flexible abstraction of reactive components called Relational Mode Automata (RMA), allowing the representation of reactive components at various levels of abstraction, to achieve different tradeoffs in analysis performance and precision. Relational mode automata can be constructed automatically from the disjunctive relational summary of the step procedure implementing a given reactive component. The core idea of relational mode automata is that component behavior can be described by a collection of component modes and the possible transitions between them.

We described a reachability analysis of RMA which is able to analyze a parallel composition of reactive components without constructing the synchronous product of automata prior to the analysis. Only the part of the product found to be reachable is constructed.

We shown that the analysis results of RMA can be computed once and for all and used to analyze component instantiations in a larger reactive system. We gave several heuristics to adapt the level of abstraction of RMA, either by merging modes or by the internal reduction of modes themselves, and through the use of disjunctive invariants.

We applied our approach to the analysis of an example of reactive system from a real proposition for an automated subway control system. Although it has been greatly simplified for clarity, it retains its core train regulation strategy.

Our objective was to guarantee the absence of arithmetic overflows at runtime by proving automatically that all variables in a train are bounded at all times. We were interested in the pure discovery of variable bounds, as they are not provided explicitly in the system definition. The analysis results of the RMA for an individual train were used in a modular way to discover constraints on the initial placement of trains on a track ensuring that the subway system is safe.

Although wider experiments should be conducted on a significant set of real-world reactive programs, we believe that our approach based on relational mode automata is humbly paving the way toward a modular analysis of reactive systems for numerical properties. In order to achieve this goal, some questions should be addressed by future works:

1. The automatic construction of RMA from disjunctive relational summaries of step procedures was described in 8.1 on the example of the counter step procedure. Either the counter step procedure or the metro step procedure were written manually in C, in a particular form, where the values of memory variables are tested first and secondly input variables are tested to determine the current reaction of the component. It enables our two-level refinement scheme to produce clean and simple disjunctive summaries by identifying syntactically the tests on memory vari-

Definition 2 . 1 . 1 (

 211 Control-Flow Graph). A control-flow graph (or CFG) is a directed graph G = (N, E) such that: • N = {ν 0 , ..., ν n } is a finite set of nodes being of one of the following types: start node, junction node or statement node. A partial transfer function f ν : D → D ⊥ is associated to each statement node ν, where D = Vars → Values is the set of variable valuations. • E ⊆ N × N is a set of control-flow edges. Start nodes have no incoming edge whereas statement nodes have only one incoming edge and junction nodes can have several incoming edges.

ν is a junction node 6 Figure 2 . 1 :

 621 Figure 2.1: Simple program with a while loop incrementing a variable i at each iteration. It is represented by the control flow graph on its right.

Definition 2 . 2 . 1 (

 221 Partially ordered set). A partially ordered set (D, ) is a non-empty set D and a binary relation over D satisfying the following properties: ∀a, b ∈ D, a b (reflexivity) ∀a, b, c ∈ D, a b ∧ b c ⇒ a c (transitivity) ∀a, b ∈ D, a b ∧ b a ⇒ a = b (antisymmetry) An element m ∈ D is an upper bound of S ⊆ D if ∀x ∈ S, x m. An element M ∈ D is the least upper bound of S, denoted as S, if M

Definition 2 . 3 . 3 (

 233 Sound approximation). Let (D, D , D , D , ⊥ D , D ) and (D , , , , ⊥, ) be complete lattices related by a Galois connection (α, γ). A function F : D → D on D is a sound approximation of a concrete function F : D → D if it satisfies the following property:

Theorem 2 . 3 . 1 (

 231 Fixpoint Transfer Theorem). Let (D, D , D , D , ⊥ D , D ) and (D , , , , ⊥, ) be complete lattices related by a Galois connection (α, γ). Let F : D → D be a monotonic function on D and let F : D → D be a monotonic function on D such that F is a sound approximation of F . The least fixpoint lfp(F ) of F and the least fixpoint lfp(F ) of F are related as follows: lfp(F ) D γ(lfp(F ))

  100] [1, 100] [100, +∞] [100, +∞] [-∞, +∞] [0, 0] [0, 100] [1, 100] [1, 100] [100, 100] [100, 100]

Figure 2 . 2 :

 22 Figure 2.2: Unbounded convex polyhedron representing the set of constraints x + 4y ≥ 7, x + 2y ≥ 5, x ≥ 1, y -x ≤ 3, 4y -x ≤ 21 and the system of generators with the set of vertices V = {(3, 1), (1, 2), (1, 4), (3, 6)} and the set of rays R = {(4, 1), (4, -1)}.

Figure 2 . 3 :

 23 Figure 2.3: Intersection and convex hull of convex polyhedra.

Figure 2 . 4 :

 24 Figure 2.4: A loop with two phases.

Figure 2 . 5 :

 25 Figure 2.5: An example of trace partitioning to prove the absence of division by zero at node ν 5 .

Definition 3 . 1 . 3 (

 313 Distributive data flow framework). A distributive data flow framework (L, F ) is a data flow framework (L, F ) where the propagation functions f : L → L in the set F are distributive for the operation of the semilattice L as follows:

  The relation R f is the union of the singleton set {(0, 0)} representing the empty set, the set {(0, y) | y ∈ f (∅)} representing the images of the empty set by the function f and the set {(x, y) | y ∈ f ({x}) ∧ y / ∈ f (∅)} of pairs made of elements of L and their images by the function f . The set (L ∪ {0}) has |L| + 1 elements, the lattice L having a finite cardinality |L|. Thus the representation relation R f of a propagation function f can be thought as a graph with 2(|L| + 1) nodes and (|L| + 1) 2 edges. Example 3.2.1. The representation relation R f of the function f : P({a, b, c}) → P({a, b, c}) such that ∀S ∈ P({a, b, c}), f (S) = {a} is defined as follows:

Definition 4 . 1 . 3 (

 413 Restriction of a relation). For a binary relation ρ ∈ R and S i , S j ∈ δ, we define the restricted relation ρ(S i , S j ) as follows:

Figure 4 . 1 :

 41 Figure 4.1: Graphical illustration of the forward fixpoint characterization of ρ (S i , S j ) for i = j.

Figure 4 . 2 :

 42 Figure 4.2: Example program implementing the classical Euclidean division by the method of successive subtractions.

Figure 4 . 3 :

 43 Figure 4.3: System of abstract fixpoint equations associated to the Euclidean division example using LRA.

Figure 5 . 1 :

 51 Figure 5.1: The simple abs procedure computing the absolute value of the parameter x and storing the result in r.

Definition 5 . 2 . 1 (

 521 Disjunctive Refinement of an Abstract Relation). Let p be a procedure described by a transition system (S, ρ, I, E) with I ⊆ S being the global precondition of p and I = α(I) being the abstraction of the global precondition I. Let δ = {S 1 , ..., S n } be an abstract partition of the set S of states.

Definition 5 . 2 . 2 (

 522 We are interested in computing disjunctive relational summaries of procedures directed by the initial values of parameters leading to that behavior. Each of these sets of initial values should be a distinct subset I k ⊆ I of the global precondition I of the procedure. They should form a partition δ I = {I 1 , ..., I m } of the global precondition I of the procedure. We should thus construct disjunctive relational procedure summaries from an abstract partition δ I = {I k = α(I k ) | I k ∈ δ} of the global precondition I of the procedure. We can construct a disjunctive refinement R = {r 1 , ..., r m } of the abstract transitive closure ρ (I , S j ) from an abstract partition δ I = {I 1 , ..., I m } of the global precondition I by computing: r k = ρ (I k , S j ) for each I k ∈ δ I of the abstract partition δ I . Precondition partitioning). The disjunctive refinement R = {r 1 , ..., r m } of ρ (I , S j ) according to the abstract partition δ I of the global precondition I is defined as: ∀k ∈ {1, ..., m}, r k = ρ (I k , S j )

Figure 5 . 3 :Example 5 . 3 . 1 .

 53531 Figure 5.3: Illustration of the complement d of an abstract value d .

Definition 5 . 3 . 3 (

 533 Refinement According to Local Reachability). Let p be a procedure represented by a transition system (S, ρ, I, E). Let I be the abstract global precondition of the procedure p, such that I = γ(I ). Let δ = {S 1 , ..., S n } be a finite abstract partition of the set S of states.Let {r ∇ k (I , S k )} k=1...n be the result of a relational analysis of the procedure p from the abstract precondition I , such that each abstract relation r ∇ k (I , S k ) of the result is an approximation of ρ (I , S k ).For a given member S k ∈ δ of the abstract partition δ of S, the abstract sourceI k = src (r ∇ k (I , S k ))of the abstract relation r ∇ k (I , S k ) discovered for S k is a necessary precondition for S k to be reachable. If s is a complementable abstract value such that: 1. I k s 2. I = I s = ⊥ and I = I s = ⊥ then I and I are refining the global abstract precondition I . The condition I is a sufficient precondition for S k to be unreachable. We denote as RLR k (I ) = {I , I } a refinement according to local reachability of the global abstract precondition I into the two new abstract preconditions I and I , with respect to the abstract relation r ∇ k (I , S k ) discovered for S k by a relational analysis starting with I .

1 :← 9 :

 19 procedure BUILD SUMMARY(I , θ) Analyze the procedure p with a relational analysis starting with I k 8:S ( ) ← S ( ) ∪ {r ( ) k (I k , E )} Ref ← REFINE(I k , r until (P ( ) = P ( -1) ) ∨ (|S ( ) | = θ)

2 .

 2 Thus according to criterion of the refinement according to local reachability, the abstract preconditions I

Figure 5 . 4 :

 54 Figure 5.4: Definition of the f91 procedure.

2 =

 2 (x ≤ 100)

  (x ≥ 101 ∧ y = x -10)and likewise under the precondition I

  condition s = (x + 11 ≥ 101) at the first recursive call. We obtain two new abstract preconditions I

Figure 6 . 1 :Figure 6 . 2 :

 6162 Figure 6.1: Overview of the mars tools.

Figure 6 . 3 :

 63 Figure 6.3: Signature for abstract domain modules.

Figure 6 . 4 :

 64 Figure 6.4: Signature for the scheduler modules.

Figure 6 . 6 :Figure 6 . 7 :

 6667 Figure 6.6: Translation of a simple if statement.

Figure 7 . 1 :

 71 Figure 7.1: Representation of a reactive program as a single infinite loop.

Figure 7 . 2 :

 72 Figure 7.2: Equational and graphical descriptions of a simple data-flow program.

Figure 7 . 3 :

 73 Figure 7.3: Definition of the Sum node with its representation as an operator network.

Example 7 . 4 . 1 .Figure 7 . 4 :

 74174 Figure 7.4: Step procedure implementing the Sum node represented in Figure 7.3.

Figure 7 . 5 :

 75 Figure 7.5: Definition and graphical representation of the Lustre node double copy.

Figure 7 . 6 :

 76 Figure 7.6: Structured reactive program with sub-components.

Figure 7 . 7 :

 77 Figure 7.7: Composition of a reactive component C with an observer O.

Figure 8 . 1 :

 81 Figure 8.1: Step procedure of the bounded event counter.

Figure 8 . 2 :

 82 Figure 8.2: The bounded event counter component.

  . I k = I k s = ⊥ and I k = I k s = ⊥ then I k and I k are refining the precondition I k according to memory variables. Definition 8.2.2 (Refinement with respect to input variables). Let X be the set of input variables. If s is a complementable abstract value such that: 1. Q i (I k ) ↓ {M 0 , X} s 2. I k = I k s = ⊥ and I k = I k s = ⊥ then I k and I k are refining the precondition I k according to input variables.

Figure 8 . 3 :

 83 Figure 8.3: Partitioning of I according to preconditions on memory variables.

Figure 8 . 4 :

 84 Figure 8.4: Partitioning of I .

Figure 8 . 5 :

 85 Figure 8.5: Partitioning of I and the associated members r 1 , r 2 , r 3 , r 4 , r 5 of the summary S c regrouped into disjunctions m 0 , m 1 , m 2 of linear relations.

  is a map associating a binary relation φ( ) ∈ Modes on variable valuations to each control location ∈ Loc. The relation φ( ) is called the mode associated to the control location . • τ ⊆ Loc × Loc is the control transition relation.

Figure 8 . 6 :

 86 Figure 8.6: Relational mode automaton R ev representing the bounded event counter component.

( 1

 1 , 2) k ∈ D the abstract value associated to a pair ( 1 , 2 ) of locations.

Figure 9 . 2 :

 92 Figure 9.2: A subway track.

Figure 9 . 3 :

 93 Figure 9.3: Partitioning tree of I according to preconditions on memory variables.

of I 2

 2 Under precondition I 2 , we get Q 8 (I 2 ) = ⊥, Q 11 (I 2 ) = ⊥, Q 16 (I 2 ) = ⊥ and Q 19 (I 2 ) = ⊥. We do not consider the program points 4, 5, 6 since they are guarded by tests depending on inputs. The test *delta >= 10 depends on the current value of delta which is computed by the statement *delta = *delta + s -b involving input variables s and b. Thus I 2 can not be refined further according to memory variables.

of I 5

 5 Under precondition I 5 , we get Q 19 (I 5 ) = ⊥. As for other preconditions, I 5 can not be refined at Q 16 guarded by *delta >= 0. Abstract Partition on Memory Variables We get an abstract partition δ m = {I 1 , I 2 , I 3 , I 4 , I 5 , I 5 } of the global precondition I .9.1.2 Refinement on Input VariablesRefinement of I 2 We get for Q 4 (I 2 ) under precondition I 2 :Q 4 (I 2 ) = (init 0 = 0 ∧ ontime 0 = 1 ∧ delta = delta 0 + s -b ∧ onbrake = onbrake 0 ∧ stopped = stopped 0 ∧ ontime = 0 ∧ nbrake = 0 ∧ late = 1 ∧ init = 0 ∧ b + delta ≤ delta 0 + 1 ∧ b + delta ≥ delta 0 ∧ 0 ≤ late 0 ≤ 1 ∧ 0 ≤ onbrake ≤ 1 ∧ 0 ≤ stopped ≤ 1 ∧ delta ≥ 10 ∧ b ≥ 0) Q 4 ↓ {M 0 , X} = (init 0 = 0 ∧ ontime 0 = 1 ∧ delta 0 + s ≥ 10 + b ∧ 0 ≤ b ≤ 1 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ late 0 ≤ 1 ∧ 0 ≤ onbrake 0 ≤ 1 ∧ 0 ≤ stopped 0 ≤ 1)We can refine I 2 into I 6 and I 6 at program point 2, according to the constraint delta 0 + s ≥ 10 + b and its complement delta 0 + s < 10 + b which involve input variables.

I 2 I 6 delta ≥ 10 ∧ late = 1 I 6 I 7 delta ≤ - 10 ∧ onbrake = 1 I 7 - 9 ≤ 1 ontime 0 = 1 Figure 9 . 4 : 1 ) 3 I 8 1 I 8 delta > 0 ∧ late = 1 late 0 = 1 Figure 9 . 5 : 9 Example: A Subway Control System Refinement of I 3 Q 9 (I 3 )I 8 = 4 I 9 1 I 9 I= 1 Figure 9 . 6 :Refinement of I 4 Q 12 (I 4 ) 9 QRefinement of I 5 Q 17 (I 5 ) 5 I 11 delta ≥ 0 ∧ ontime = 1 I 11 delta ≤ - 1 ∧ stopped = 1 stopped 0 = 1 Figure 9 . 7 : 5 Figure 9 . 8 :

 261016710179119413818119593938491919641249517551111111197598 Figure 9.4: Partitioning of I 2 according to input variables, with the ranges of possible values for delta under preconditions I 7 , I 7 , I 6 .

r 1 = 9

 19 (init 0 = 1 ∧ init = 0 ∧ ontime = 1 ∧ stopped = 0 ∧ onbrake = 0 ∧ late = 0 ∧ nbrake = 0 ∧ delta = 0 ∧ 0 ≤ late 0 ≤ 1 ∧ 0 ≤ onbrake 0 ≤ 1 ∧ 0 ≤ ontime 0 ≤ 1 ∧ 0 ≤ stopped 0 ≤ 1 ∧ 0 ≤ b ≤ 1 ∧ 0 ≤ s ≤ 1) r 2 = (init 0 = 0 ∧ ontime 0 = 1 ∧ late = 1 ∧ delta = delta 0 + s -b ∧ onbrake = onbrake 0 ∧ stopped = stopped 0 ∧ ontime = 0 ∧ nbrake = 0 ∧ init = 0 ∧ delta 0 + 1 ≥ b + delta ∧ b + delta ≥ delta 0 ∧ 0 ≤ b ≤ 1 ∧ 0 ≤ late 0 ≤ 1 ∧ 0 ≤ onbrake ≤ 1 ∧ 0 ≤ stopped ≤ 1 ∧ delta ≥ 10)ChapterExample: A Subway Control Systemr 3 = (init 0 = 0 ∧ ontime 0 = 1 ∧ onbrake = 1 ∧ delta ≤ -10 ∧ delta = delta 0 + s -b ∧ nbrake = b ∧ late = late 0 ∧ stopped = stopped 0 ∧ ontime = 0 ∧ init = 0 ∧ delta 0 + 1 ≥ b + delta ∧ 0 ≤ b ≤ 1 ∧ 0 ≤ late ≤ 1 ∧ 0 ≤ onbrake 0 ≤ 1 ∧ 0 ≤ stopped ≤ 1 ∧ b + delta ≥ delta 0 ) r 4 = (init 0 = 0 ∧ ontime 0 = 1 ∧ ontime = 1 ∧ delta = delta 0 + s -b ∧ -9 ≤ delta ≤ 9 ∧ onbrake = onbrake 0 ∧ stopped = stopped 0 ∧ nbrake = 0 ∧ init = 0 ∧ delta 0 + 1 ≥ b + delta ∧ 0 ≤ b ≤ 1 ∧ 0 ≤ late ≤ 1 ∧ 0 ≤ onbrake ≤ 1 ∧ 0 ≤ stopped ≤ 1 ∧ b + delta ≥ delta 0 ) r 5 = (init 0 = 0 ∧ late 0 = 1 ∧ ontime = 1 ∧ late = 0 ∧ delta = delta 0 -b ∧ s = 0 ∧ onbrake = onbrake 0 ∧ stopped = stopped 0 ∧ ontime 0 = 0 ∧ nbrake = 0 ∧ init = 0 ∧ 0 ≤ b ≤ 1 ∧ delta ≤ 0 ∧ 0 ≤ onbrake ≤ 1 ∧ 0 ≤ stopped ≤ 1) r 6 = (init 0 = 0 ∧ late 0 = 1 ∧ late = 1 ∧ delta ≥ 1 ∧ delta = delta 0 -b ∧ s = 0 ∧ ontime 0 = 0 ∧ ontime = 0 ∧ nbrake = 0 ∧ init = 0 ∧ 0 ≤ b ≤ 1 ∧ 0 ≤ onbrake ≤ 1 ∧ 0 ≤ stopped ≤ 1) r 7 = (init 0 = 0 ∧ onbrake 0 = 1 ∧ ontime = 1 ∧ onbrake = 0 ∧ delta ≥ 0 ∧ delta = delta 0 + s -b ∧ stopped = stopped 0 ∧ ontime 0 = 0 ∧ nbrake = 0 ∧ late 0 = 0 ∧ late = 0 ∧ init = 0 ∧ delta 0 + 1 ≥ b + delta ∧ b + delta ≥ delta 0 ∧ 0 ≤ b ≤ 1 ∧ 0 ≤ stopped ≤ 1) r 8 = (init 0 = 0 ∧ onbrake 0 = 1 ∧ stopped = 1 ∧ onbrake = 0 ∧ delta ≤ -1 ∧ delta = delta 0 + s -b ∧ nbrake = nbrake 0 ∧ ontime 0 = 0 ∧ ontime = 0 ∧ late 0 = 0 ∧ late = 0 ∧ init = 0 ∧ delta 0 + 1 ≥ b + delta ∧ b + delta ≥ delta 0 ∧ 0 ≤ b ≤ 1 ∧ 0 ≤ stopped 0 ≤ 1 ∧ nbrake ≥ 10) r 9 = (init 0 = 0 ∧ onbrake 0 = 1 ∧ onbrake = 1 ∧ delta = delta 0 + s -b ∧ stopped = stopped 0 ∧ ontime 0 = 0 ∧ ontime = 0 ∧ late 0 = 0 ∧ late = 0 ∧ init = 0 ∧ nbrake =nbrake 0 + b ∧ delta 0 + 1 ≥ b + delta ∧ 0 ≤ b ≤ 1 ∧ delta ≤ -1 ∧ 0 ≤ stopped ≤ 1 ∧ nbrake ≤ b + 9 ∧ b + delta ≥ delta 0 ) r 10 = (init 0 = 0 ∧ stopped 0 = 1 ∧ ontime = 1 ∧ delta = delta 0 + s ∧ stopped = 0

Figure 9 . 8 . 0 m 1 m 2 m 3 m 4 Figure 9 . 9 :

 980123499 Figure 9.9: Relational Mode Automaton R train .

1 )

 1 ∧ ((-9 ≤ delta ≤ 9 ∧ ontime = 1 ∧ delta = delta 0 + s -b ∧ late = late 0 ∧ stopped = stopped 0 ∧ onbrake = onbrake 0 ∧ nbrake = 0) ∨ (delta ≥ 10 ∧ late = 1 ∧ delta = delta 0 + s -b ∧ stopped = stopped 0 ∧ onbrake = onbrake 0 ∧ nbrake = 0 ∧ ontime = 0) ∨ (delta ≤ -10 ∧ onbrake = 1 ∧ delta = delta 0 + s -b ∧ stopped = stopped 0 ∧ nbrake = b ∧ late = late 0 ∧ ontime = 0)) φ( late ) = (late 0 = 1 ∧ ontime 0 = 0 ∧ 0 ≤ stopped 0 ≤ 1 ∧ 0 ≤ onbrake 0 ≤ 1 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ b ≤ 1) ∧ ((delta ≥ 1 ∧ late = 1 ∧ delta = delta 0 + s -b ∧ s = 0 ∧ ontime = ontime 0 ∧ onbrake = onbrake 0 ∧ stopped = stopped 0 ∧ nbrake = 0) ∨ (delta ≤ 0 ∧ ontime = 1 ∧ delta = delta 0 + s -b ∧ stopped = stopped 0 ∧ onbrake = onbrake 0 ∧ nbrake = 0 ∧ late = 0)) φ( onbrake ) = (onbrake 0 = 1 ∧ ontime 0 = 0 ∧ late 0 = 0 ∧ 0 ≤ stopped 0 ≤ 1 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ b ≤ 1) ∧ ((delta ≤ -1 ∧ onbrake = 1 ∧ delta = delta 0 + s -b ∧ late = late 0 ∧ stopped = stopped 0 ∧ nbrake = nbrake 0 + b ∧ ontime = ontime 0 ∧ nbrake 0 ≤ 9) ∨ (delta ≥ 0 ∧ ontime = 1 ∧ delta = delta + s -b ∧ late = late 0 ∧ stopped = stopped 0 ∧ onbrake = 0 ∧ nbrake = 0) ∨ (nbrake 0 ≥ 10 ∧ stopped = 1 ∧ delta = delta 0 + s -b ∧ late = late 0 ∧ onbrake = 0 ∧ nbrake = nbrake 0 ∧ ontime = ontime 0 )) φ( stopped ) = (stopped 0 = 1 ∧ ontime 0 = 0 ∧ onbrake 0 = 0 ∧ late 0 = 0 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ b ≤ 1) ∧ ((delta ≤ -1 ∧ stopped = 1 ∧ delta = delta 0 + s -b ∧ b = 0 ∧ nbrake 0 ≥ 10 ∧ late = late 0 ∧ onbrake = onbrake 0 ∧ nbrake = nbrake 0 ∧ ontime = ontime 0 ) ∨ (delta ≥ 0 ∧ ontime = 1 ∧ delta = delta 0 + s -b ∧ late = late 0

Y ontime 0 = (ontime = 1 ∧

 01 stopped = 0 ∧ onbrake = 0 ∧ nbrake = 0 ∧ late = 0 ∧ delta = 0 ∧ 0 ≤ s ≤ 1 ∧ 0 ≤ b ≤ 1) Y ontime k+1 = Y ontime k ∇ ontime (Y ontime k post( ontime , ontime )(Y ontime k ))

  in stopped = post( onbrake , stopped )(G onbrake ) = (stopped = 1 ∧ ontime = 0 ∧ onbrake = 0 ∧ nbrake = 10 ∧ -19 + s ≤ delta ≤ s -1 ∧ late = 0 ∧ 0 ≤ s ≤ 1 ∧ b = 0)We compute a local increasing sequence at stopped , we get:G stopped = (stopped = 1 ∧ ontime = 0 ∧ onbrake = 0 ∧ nbrake = 10 ∧ late = 0 ∧ b = 0 ∧ delta ≤ -1 ∧ 0 ≤ s ≤ 1 ∧ delta ≥ s -19)9.4 Modular Analysis of a Pair of TrainsThe variable delta is bounded at every reaction step:G ontime ↓ delta = (-9 ≤ delta ≤ 9) G late ↓ delta = (1 ≤ delta ≤ 10) G onbrake ↓ delta = (-19 ≤ delta ≤ -1) G stopped ↓ delta = (-19 ≤ delta ≤ -1)

  .3.

	module type Domain =
	sig
	(* Type of abstract domain elements *)
	type t
	(* Type of the domain manager *)
	type man
	(* Create the domain manager *)
	val create : unit -> man
	(* Operators *)
	val bottom : man -> t
	val top : man -> t
	val join : man -> t list -> t
	val meet : man -> t -> t -> t
	val widening : man -> t -> t -> t
	val is_bottom : man -> t -> bool
	val is_top : man -> t -> bool
	val is_leq : man -> t -> t -> bool
	end

  Test statements in the source language, such as if statements in C, are encoded by a splitting of the test condition, through assume cond statements in statement nodes denoting the several possible outcomes of a test condition. We give examples below.

Example 6.3.1 (Simple if statement). This simple if statement is encoded by the fragment of the mars intermediate representation given in the right-hand side.

Table 6 .

 6

	programs, are very

1: Experimental results.

Table 6 .

 6 • Procedure summaries only depend on the summaries of called procedures and could be computed in parallel according to the dependencies given in the call graph of the program.

	Program	Function	Time (s)	τ c
	fabs	fabs	0.001	0.067
	fdct	fdct	0.050	0.588
	fft1	my fabs	< 0.001	0.001
		my sin	0.002	0.004
		my cos	< 0.001	0.001
		my log	< 0.001 < 0.001
		fft1	0.350	0.753
	fir	fir	0.019	0.267
	janne	janne	0.037	0.602
	minver	mmul	0.047	0.069
		minver fabs	< 0.001 < 0.001
		minver	0.616	0.897
	my sin	my sin	0.003	0.098
	jfdctint	jpeg fdct islow	0.031	0.528
	ludcmp	fabs	< 0.001	0.002
		ludcmp	0.055	0.540
	ns	foo	0.011	0.215
	qurt	qurt fabs	< 0.001	0.007
		qurt sqrt	0.004	0.138
		qurt	0.002	0.066
	select	select	0.042	0.730
	ud	ludcmp	0.050	0.425
	cnt fdct	fdct	0.070	0.941
	cnt fft1	my fabs	0.001	< 0.001
		my sin	0.004	0.001
		my cos	< 0.001 < 0.001
		my log	< 0.001 < 0.001
		fft1	1.750	0.661
	cnt jfdctint jpeg fdct islow	0.035	0.500
	cnt ns	foo	0.026	0.382
	cnt qurt	qurt fabs	0.001	0.010
		qurt sqrt	0.019	0.308
		qurt	0.003	0.047
	cnt minver mmul	0.126	0.037
		minver fabs	< 0.001 < 0.001
		minver	2.925	0.854

2: Summaries computation times.

  .1.

	void counter_step(int n, int init, int event, reset, int * cnt)
	{
	assert(n >= 1);
	1: if(init){
		*cnt = event;
	2: } else {
	3:	if(reset){
		*cnt = event;
	4:	} else if(*cnt < n) {
		*cnt = *cnt + event;
	5:	} else {
	6:	}
	7: }
	8:
	}

  Example 8.7.1. For R ev representing the bounded event counter, we computed in 8.4.2 the following approximations of sets of reachable valuations:

	8.7 Invariants
	.7 Invariants
	8.7.1 Invariant of a Relational Mode Automaton
	Let reach : Loc → D be the function associating approximations of the sets of reachable
	variable valuations at each control location of a relational mode automaton R. The
	invariant inv(R) is defined as:
	inv(R) =	reach ( )
	∈Loc

X 0 = Z X 1 = {0} X 2 = {0, 1} X 3 = {1, 2} X 4 = {1, 2} X 5 = ∅ X 6 = ∅ X 0 = Z X 1 = {0} X 2 = {0, 1, 2} X 3 = {1, 2, 3} X 4 = {1, 2, 3} X 5 = ∅ X 6 = ∅ X 0 = Z X 1 = {0} X 2 = {0, 1, 2, 3} X 3 = {1, 2, 3, 4} X 4 = {1, 2, 3, 4} X 5 = ∅ X 6 = ∅

sv-comp.sosy-lab.org/2018/benchmarks.php

alice.cri.mines-paristech.fr/models.html

www.mrtc.mdh.se/projects/wcet/benchmarks.html

Acknowledgements

I thank Antoine Miné and Andreas Podelski for reviewing this manuscript and for their remarks. I thank Cesare Tinelli, Corinne Ancourt, Olivier Bouissou and Susanne Graf for taking part in this thesis jury.

I thank my advisor Nicolas Halbwachs for having given me the amazing opportunity to work with him, since my TER research internship five years ago. This work would not have been possible without him. I am grateful and indebted to his immense wisdom, vast scientific knowledge, his constant support and great availability.

I thank Claire Maiza and Fabienne Carrier for their support and for giving me the chance to discover research in computer science during my L3 magistère internship.

I thank my fellow colleagues and students from Verimag and the IMAG building, most notably Valentin, Yanis, Clément, Cyril, Vincent, Matheus, Bai and Maëva for their friendship and all the meals and discussions that we shared during these three years. I thank Valentin for all the interesting and passionate discussions that we had about abstract interpretation, the most arcane areas of computer science and various other subjects during la pause.

I thank my friends from university Raphaël and Timothée for their companionship. I thank Adam, Damien, Romain and Théotime for being the most amazing friends since all this time.

I thank Jérémy for being my friend and being in my life since our first days at university, and also as one of the most talented persons I have the honor to know.

I would like to thank my grandfather, who gave me a taste for science since an early age. He transmitted me his love for the subtle art and exact science of tinkering, finding creative technical solutions, and encouraged me to listen to the amazing stories that old books and objects are waiting to tell.

I would like to thank my grandmother Jeanne for her wisdom, for teaching me the benefits of hard work and various rare skills.

I thank my parents and my brother for their constant and unwavering support, especially in times of doubt and adversity. My parents transmitted me the values of gentleness, openness and striving for what is right. They showed me how to be curious about the world around us. I am especially grateful for the Sunday family tradition of forest walks and exploration of all sorts of ancient, mysterious or simply long-forgotten buildings and places.

6.4 Non-duplication of Procedure Parameters More complex conditions are translated, in a classical fashion, into a DAG of assume statements, to respect the short-circuit evaluation semantics of boolean operators in C. Example 6.3.3. We give an example of the translation of an if statement with a condition containing boolean operators, respecting the semantics of short-circuit evaluation in C.

Non-duplication of Procedure Parameters

We assumed in our formal setting, for clarity, that procedure parameters are duplicated during the computation of a relational summary. We proposed to introduce for each formal parameter x an additional variable x 0 denoting the initial value of x. This duplication can become costly as it increases the number of variables in abstract values, and in particular for Linear Relation Analysis, the dimension of convex polyhedra. We should note that this duplication is not necessary for pure-value or pure-result parameters, which are parameters whose values are respectively not modified or not used before being modified. The initial value of a pure-value parameter is indistinguishable from its final value and the initial value of a pure-result parameter can not be referred to. We do therefore in practice a pre-analysis to determine the status of procedure parameters, that is whether they are pure-value, pure-result or value-result parameters. We describe the design of this specific data-flow analysis.

Boolean attributes

We associate with each formal parameter X of a procedure, three boolean attributes X i , X c , X u which are defined as follows:

• X i is true when X is certainly equal to its initial value X 0 • X c is true when the value of X has certainly been changed • X u is true when the value of X may have been used Quite clearly, we have the following properties for the attributes:

• X is a pure value-parameter if X i is true at each exit point of the procedure.

• X is a pure result-parameter if X c is true whenever X u is true.

We then define how these attributes are initialized and propagated along the nodes of the control-flow graph of a procedure.

The control transition relation τ is defined as: τ = {( 0 , 1 ), ( 1 , 1 ), ( 1 , 2 ), ( 2 , 2 ), ( 2 , 1 )}

Semantics

State Transition System

For a given relational mode automaton R, we define a state transition system T R = (S, I, → R ), where the set S of states is S = Loc × V(V ) and the state transition relation → R ⊆ S × S is defined as follows:

The state transition system T R is called the state semantics of the relational mode automaton R.

Post-Condition Operator

For each pair ( , ) of control locations, we define a post-condition operator post( , ) : P(V(V )) → P(V(V )) giving the image of a set U ⊆ V(V ) of valuations by the mode φ( ), assuming that the next mode is φ( ). When modes can be arbitrary relations, the post( , ) operator is defined as follows:

When modes φ( ), φ( ) ∈ P(D ) are disjunctions of abstract values in D the post( , ) operator is more specifically defined as:

Reachable Valuations

The reachable states at a given control location ∈ Loc are the states ( , σ) which are reachable from the initial control location 0 in a finite number of computation steps of the state transition system T R . We define the set reach( ) of reachable valuations at a control location ∈ Loc as:

The set reach( ) can be expressed as the least solution of the following system of fixpoint equations:

Substitution

We define a way to get a new relational mode automaton from an already defined one, by variable substitution. It is intended as a templating mechanism for relational mode automata.

Let R = (X, Y, Z, M, I, Loc, l 0 , φ, τ ) be a relational mode automaton and V = X ∪ Y Z ∪ M . Let W = (w 1 , ..., w m ) and W = (w 1 , .., w m ) be two distinct tuples of variables of equal length with V ∩ W = ∅. Definition 8.3.2 (Variable Renaming). We denote as K[W/W ] the renaming in K of each variable w i ∈ W by the variable

Definition 8.3.4 (Variable substitution in RMA). We define the renamed relational mode automaton R[W/W ] = (X , Y , Z , M , I , Loc, 0 , φ , τ ) as follows:

Parallel Composition

Two relational mode automata R 1 , R 2 can have distinct sets V 1 , V 2 of variables and thus states with valuations defined over different sets of variables. The parallel composition of R 1 and R 2 must have states with valuations keeping track of the variables of both automata, defined over a greater set V = V 1 ∪ V 2 of variables. In order to properly define the parallel composition of R 1 and R 2 , we must extend the modes of R 1 and R 2 to the greater set V of variables.

Definition 8.3.5 (Extension of valuations). Let V k and V be finite sets of variables such that V k ⊆ V . We define the extension

) to a set of valuations over V as:

Each extended valuation σ ∈ σ k ↑ V coincides with the original valuation σ k on the variables of V k , preserving their values, such that σ ↓ V = σ k . The extension σ k ↑ V is the set of all possible valuations σ of V satisfying this criterion.

The extension of valuations over a greater set V can be seen, in some sense, as introducing degrees of freedom for the variables of V which are not in V k . The other variables are allowed to to range freely over the set of all possible values.

The extensions to V of the valuations σ 1 and σ 2 are:

The set I s of initial variable valuations is:

The function φ s :

) is defined as:

The control transition relation τ s ⊆ Loc s × Loc s is defined as:

)

2 )) and φ s ((l 1 2 , l 2 1 )) are not reachable in any concrete execution of the product automaton R s . As both counters are reacting to the same event and initialized to the same value, they must be equal at each step. Although intuitively simple and quite obvious, the equality of counters involves, in some sense, the dynamics of the product automaton, which are not considered in the definition of the parallel product.

The actually reachable structure, made of reachable modes only, should be much smaller. Since the reachability of modes in a relational mode automaton is undecidable in general, we turn once more to the abstract world.

Local Decreasing Sequences

The decreasing sequence (Z i ) i≥0 at a control location starting with the limit Y ∇ of the increasing sequence (Y i ) i≥0 is defined as:

We denote as Ω (d ) = Z the limit of the local decreasing sequence at , computed from the limit of an increasing sequence (Y i ) i≥0 starting with d ∈ D .

Global Increasing Sequence

We denote as (G k ) k≥0 the global increasing sequence computed over the entire relational mode automaton. The terms of (G k ) k≥0 belongs to the product domain (D ) L , where L = |Loc| is the number of control locations. For each term G k , we denote as

Incoming Value At each step of the global sequence, local sequences are started on values obtained at predecessor locations. The incoming abstract value in (G k ) ∈ D to a control location is:

Global Transfer Function The global transfer function F G : (D ) L → (D ) L computes a local increasing and decreasing sequence at each control location starting with in (G k ):

The global increasing sequence (G k ) k≥0 is defined as follows:

We denote as G ∇ the limit of the global increasing sequence (G k ) k≥0 .

Global Decreasing Sequence

The global decreasing sequence is defined as:

We denote as G the limit of the decreasing sequence (G i ) i≥0 . The approximation of the set of reachable valuations at a control location is reach ( ) = G .

Reachability Analysis of the Bounded Event Counter

We compute a reachability analysis of the relational mode automaton R ev defined in Example 8.3.1. The global increasing sequence starts with G 0 = ⊥ for each location .

Global Iteration 1

Location 0 The incoming abstract value in 0 (G 0 ) to the initial location 0 is:

We obtain immediately a new value G 0 1 associated to 0 :

We compute a local increasing sequence at 1 , starting with in 1 (G 1 ), as follows:

)) The decreasing sequence converges immediately. The abstract value G 1 1 at 1 is:

Location 2 The incoming value in 2 (G 1 ) at 2 is:

The local increasing and decreasing sequence at 2 gives:

Global Iteration 2

Location 1 The incoming value at 1 is:

The local sequences at 1 gives:

, thus the global increasing sequence has converged. We get the following approximations of sets of reachable valuations:

Iterative Construction of the Control Transition Relation

Whereas the modes of a relational mode automaton can be obtained from the members of the disjunctive summary of a step procedure, the control transition relation τ can be constructed iteratively by a reachability analysis.

We compute a transition relation τ k at each iteration k ≥ 0 of the global increasing sequence (G k ) k≥0 , as follows:

In the first global term G 0 , the initial control location 0 is the only location known to be reachable with G 0 = I. We start with τ 0 = ∅. Then, at each global iteration k, we add a control transition ( , ) to τ k+1 when a location is discovered to be reachable and can be a direct successor of , which is when post( , )(G k ) dom( ) = ⊥. Finally, τ is obtained from the limit G ∇ of the global increasing sequence.

Thus we add transitions from 0 to 1 and 2 . The control transition relation becomes τ = {( 0 , 1 ), ( 0 , 2 )}. Location 1 The value G 1 1 computed at 1 is:

We examine possible transitions from 1 :

Chapter 8

Modular Analysis of Reactive Systems

We add the self-transition ( 1 , 1 ) and ( 1 , 2 ). The control transition relation becomes: .

The global increasing sequence has converged. The control transition relation of the bounded event counter is:

Analysis of a Parallel Composition of Relational Mode Automata

We can compute a reachability analysis on a parallel composition of relational mode automata in different ways.

A rather crude way is to construct explicitly the parallel product automaton as defined in 8.3.8 and to compute a reachability analysis of the product automaton. It has a quadratic number of modes with respect to the original automata. Furthermore, the parallel product does not consider the dynamic behavior of relational mode automata and many control locations of the product can be unreachable, as shown in Example 8.3.4. Thus to mitigate the cost of the explicit parallel product, we construct only the reachable part of the parallel product automaton, called the reduced product automaton, as a side-product of the reachability analysis.

We denote as Y

( 1 , 2 ) ∇ the limit of a local increasing sequence (Y

Local Decreasing Sequence

A local decreasing sequence (Z

) i≥0 at a pair ( 1 , 2 ) of locations starting with the limit Y

of the increasing sequence is defined as:

( 1 , 2 ) the limit of the local decreasing sequence at ( 1 , 2 ), computed from the limit of an increasing sequence (Y i ) i≥0 starting with d .

Incoming Value

The incoming abstract value in

Global Transfer Function The global transfer function F G : (D ) L → (D ) L computes a local increasing and decreasing sequence at each pair ( 1 , 2 ) of control locations starting with in

We denote as G the limit of the global decreasing sequence. The approximation of the set of reachable valuations at ( 1 , 2 ) is reach

Construction of the Reduced Product Automaton

The sets of variables of the reduced product automaton are defined as:

The control transition relation τ is obtained from the limit G ∇ of the global increasing sequence. The function φ : Loc 1 × Loc 2 → D associating modes to control locations is defined as:

where φ 1 ( 1 ) ∧ φ 2 ( 2 ) denotes the disjunction formed by the product of the disjunctions φ 1 ( 1 ) and φ 2 ( 2 ).

Example

We analyze the parallel product R s = R 1 × R 2 of the bounded event counters R 1 and R 2 defined in Example 8.3.4. We construct the reduced product automaton R s during the analysis. The initial term of the global increasing sequence is G 0 = ⊥ and τ = ∅.

(l 1 0 , l 2 0 )

Figure 8.12: Initially, only ( 1 0 , 2 0 ) is known to be reachable and τ = ∅.

Global Iteration 1

Location ( 1 0 , 2 0 ) The incoming abstract value to the initial location ( 1 0 , 2 0 ) of R s is:

The abstract value G

We examine the possible transitions from ( 1 0 , 2 0 ):

)) = ⊥

The locations (

Figure 8.13: The locations ( 1 1 , 2 1 ) and ( 1 2 , 2 2 ) are reachable from the initial location ( 1 0 , 2 0 ).

1 ) The incoming abstract value to ( 1 1 , 2 1 ) is:

We compute an increasing sequence at ( 11 , 2 1 ), followed by a decreasing sequence. We get the abstract value G

Chapter 8

Modular Analysis of Reactive Systems

We examine possible transitions from ( 11 , 2 1 ):

)) and a transition to ( 1 2 , 2 2 ).

1 ) and we add the self-transition on ( 11 , 2 1 ).

2 ) The incoming abstract value to

We compute an increasing and decreasing sequence at ( 1 2 , 2 2 ). We get the abstract value G

We examine the possible transitions:

)) and a transition back to ( 1 1 , ).

Figure 8.15: We add a self-transition on ( 1 2 , 2 2 ) and a transition from ( 1 2 , 2 2 ) back to ( 11 , 2 1 ).

Global Iteration 2

Location

1 ) The incoming abstract value to

We get the abstract value G

We have G

. The global increasing sequence has converged.

Reduced Product Automaton

We construct the reduced product automaton R s = (X, Y, Z, M, I 1 I 2 , Loc, ( 1 0 , 2 0 ), φ, τ ) from the analysis results. The sets of variables are

2 )}. The control transition relation τ is:

The function φ : Loc → P(V(V ) × V(V )) associating modes to control locations is:

Reduction of Relational Mode Automata

We are interested in the analysis of reactive components represented by relational mode automata at different levels of precision. The precision of a relational mode automaton can be reduced at two different levels, either by merging modes, producing an automaton with fewer modes, or from the inside of modes, by merging disjuncts for modes defined by disjunctions of abstract relations.

Reduction by Merging Modes

Principle A relational mode automaton R = (X, Y, Z, M, I, Loc, 0 , φ, τ ) can be reduced by merging some of its modes. Two modes φ( 1 ) and φ( 2 ) of R are merged by replacing the locations 1 , 2 by a fresh location / ∈ Loc where the mode associated to is the relation φ( 1 ) ∪ φ( 2 ). The control transitions originating from or leading to 1 or 2 are rewritten in terms of . If 1 or 2 is the initial location 0 , then becomes the new initial control location.

Local iteration at ontime

We compute a new incoming value at ontime with the contributions of G onbrake and G stopped .

The incoming value has not changed, thus the loop ontime , onbrake , stopped has converged.

Local iteration at late

The incoming abstract value at late is:

We compute a local increasing sequence at late , we get:

Local iteration at ontime Finally, we can compute the incoming value at ontime using the values associated to its predecessors:

The incoming value at ontime has not changed, thus the analysis of the relational mode automaton R train has converged. We discovered for each control location:

Reachability Analysis of R track

A reachability analysis of the relational mode automaton R track gives:

The projection on the numbers of beacons detected by each train is:

Thus the difference nb1 -nb2 in number of detected beacons by each train is bounded. We can use the constraint -29 ≤ nb1 -nb2 ≤ 29 for the initial placement of trains. It ensures that no collisions are possible if trains are initially separated by more than 29 beacons on a track.

Verification of the Assertion on late

We use the results of the reachability analysis of R track to prove that the assertion late = 1 ⇒ s = 0 holds for each train. It ensures that a train do not receive the time signal when it is late, which is enforced by the implementation of the global clock of the track.

The assertions late1 = 1 ⇒ s = 0 and late2 = 1 ⇒ s = 0 are verified at each location of R track and also hold when the train step procedure is called to implement each train. ables and the tests depending on input variables. Although this form may seem quite natural for a human being, it is not the case for step procedures generated automatically from synchronous languages like Lustre. We could propose a way to construct relational mode automata from general step procedures by identifying semantically the tests depending only on memory variables and the tests possibly depending on input variables. However this would involve a fairly costly dependency analysis, for a benefit not really superior in practice to the syntactical identification of tests, as the construction of RMA from step procedures should remain as cheap as possible. Instead, a more pragmatic way would be to address the compilation of synchronous programs into step procedures of the appropriate form for analysis. Classically, heuristics are used in the compilation of Lustre programs to decide where tests should be placed in the generated code. A new heuristic could be possibly devised to structure the control flow of the generated procedure in the preferred way for RMA construction. 2. We presented in 8.6 and 8.7 a catalogue of techniques to adapt the level of abstraction of RMA to analyze larger reactive systems: reduction by merging modes, internal reduction of modes, weakening of invariants, disjunctive invariants and relational augmentation. All these techniques can be combined in various ways. For the analysis of our subway, we computed a weakened disjunctive invariant of a relational mode automaton, which was augmented by linear relations given by the automaton modes.

Experiments should be conducted on the impact of these techniques on the precision of analysis results and analysis performance. Heuristics should be designed to select automatically the reduction techniques to apply during the analysis of a reactive program, depending on high-level goals: whether we want to perform the most precise analysis of a reactive program achievable with our approach, or if we want a modestly-precise analysis to put the emphasis on performance.

We devised two approaches for the modular analysis of interprocedural phenomena, being either procedures, possibly with recursion, or reactive components, which can be seen in a sense as a special case of procedures with persistent memories. Similarly, our approaches could be applied to the analysis of object-oriented programs, where objects have memory in the form of their data fields, which are persisted and can be modified by methods from one call to another.

Our approaches show that expressive relational abstract domains such as convex polyhedra can be used to compute precise procedure summaries which in turn can improve significantly analysis scalability. They give a direction toward the adoption of expressive relational abstract domains in static analysis tools for large programs.