Verifying a Real-Time Language with Constraints - Anicet BART

many operators (arithmetic operations, mathematical func- tions, etc). ... mathematical functions. All the variables ..... The proofs are classical in lattice theory. B. Constraint ..... Diagram Languages,” in International Computer Music Con- ference ...
277KB taille 2 téléchargements 263 vues
Verifying a Real-Time Language with Constraints

1

Anicet Bart1 , Charlotte Truchet2 , Eric Monfroy1 ´ TASC (CNRS/INRIA), LINA - UMR 6241, Ecole des Mines de Nantes, and Universit´e de Nantes, France 2 CELTIQUE, IRISA - UMR 6074, Rennes, France Email: {firstname}.{lastname}@univ-nantes.fr

Abstract—Formal verification of real time programs, where variables can be assigned different values at every single time, is difficult due to the analyses of loops with time lags. In this paper, we consider a problem arising from verification of realtime languages: checking of the range of stream variables. We propose a constraint model for this problem, and an algorithm, combining constraint propagation and an ad hoc solving method, for solving it. We apply our method to the FAUST language, a language for processing audio streams. Experiments show that our approach provides very good results in short times. Keywords-constraints, verification, block diagrams

I. I NTRODUCTION Constraint programing (CP) [1] offers a set of efficient methods for modeling and solving combinatorial problems. One of its key ingredients is the propagation mechanism, which reduces the search space by over-approximating the solution set. For continuous constraints ([2], [3]), propagation is defined in a generic way on a given constraint language, usually containing equalities, inequalities, and many operators (arithmetic operations, mathematical functions, etc). In this article, we present a method using this generic propagation scheme, combined with a new solving algorithm, for the resolution of a verification problem. The problem consists in checking the range of the outputs of programs written in a real-time language. More precisely, we are interested in DSP (Digital Signal Process) programs, based on a block-diagram algebra, which contains both typical real-time operations (split, merge, delay...) and mathematical functions. All the variables are infinite streams over the reals, and all the loops are infinite by construction: the programs do never stop by themselves (they may stop computing in practice because all the signals are constant), they need to be killed by the user. The problem we tackle is the following: considering a block-diagram (or the corresponding program), can we compute or approximate at a good precision the range of the stream output by this program? This problem is, in a more general form, at the core of another research area, Abstract Interpretation, as defined by [4], [5]. Abstract Interpretation offers a great variety of tools to over-approximate traces of programs to prove the absence of some runtime errors, such as overflows. It is

worth mentioning that one of these tools, the bottom-up topdown algorithm for the interval abstraction [4], [6], is the same as the HC4 constraint propagator [2] (in the following, we will refer to this algorithm as HC4), which shows how close CP and Abstract Interpretation can sometimes be. However, Abstract Interpretation operators may fail when analyzing loops, when their loop operator (widening) cannot provide precise approximations. Our application is the FAUST (Functional Audio Stream)1 language which has been designed to synthesize and treat audio streams [7]. FAUST is a functional language with a proper semantic based on block-diagrams. In practice, the compiler automatically generates a block-diagram for each program. The outputs of these block-diagrams are real-value streams which represent audio signals, these signals being sent afterwards to loudspeakers or other applications. By convention, digital audio signals must stay in the range [−1, 1]. We will focus on the verification of the stream output by the block-diagrams representing the programs. Verifying FAUST programs is essential since this language is intended for non computer scientists, and in practice, a program which exceeds the standard audio range often has conception mistakes. Moreover, FAUST programs are now used in concerts or commercial applications. FAUST already embarks a static analyzer based on Abstract Interpretation, using the interval abstract domain. The analyzer computes the outputs of each operator from its inputs, with the bottom-up top-down (or HC4) algorithm. When the programs do not have loops or delays, this works very well. However, as soon as the programs have loops, the interval analysis cannot provide precise over-approximation (returning [−∞, +∞]) and the analysis fails. In this article, we first propose a model of the verification of block-diagram as a constraint problem. Propagation based on the constraints of this problem allows us to compute over-approximation of the range of the computed streams, but as soon as the program has loops, the approximations are too large. We present a specific solving method which identifies the loops in the constraint graph, and propagates these constraints in a specific way to find over-approximation with a better precision. We implemented this method on FAUST block-diagrams, using the IEEE P1788 library of 1 FAUST

is open source and available at http://faust.grame.fr.

the IEEE Interval Standard Working Group [8] for interval arithmetic. We tested it on several programs from the FAUST library. Most of the times, the over-approximation returned by our method is optimal. This implementation is currently being integrated into the FAUST compiler. In some sense, our work can be seen as solving a constraint problem on streams. There have been other works on stream constraints in the literature (e.g., [9], [10]). However, this approach radically differs from ours because their stream constraints are meant to build an automaton whose paths are solutions of the constraints. In particular, we would not be able to analyze infinite streams in a non-regular language with these stream constraints. On the contrary, our constraints are expressed on infinite streams, and generated in order to compute hulls of the streams. There have already been several works on applications of CP techniques to verification. One of the most fruitful is probably test generation using constraints, see [11], [12] for recent works. Other approaches mix CP and Abstract Interpretation, either to refine CP techniques [13], [14] or to improve the Abstract Intepretation analysis [15]. However, to our knowledge, none of these works were applied to realtime processing. Our work thus extends the range of CP applications to verification. This article is organised as follows: Section II introduces the notion of block diagrams. Section III presents the convertion of block diagrams into constraints. Our solving algorithm is given in Section IV. Finally, Section V details the application language and presents the experimental results. II. B LOCK D IAGRAMS This section introduces the block diagrams which represent the real-time programs. A. Syntax A block is a function that applies an operator on ordered inputs, and generates one or more ordered outputs. Definition 2.1: Let E be a nonempty set. A block over E is a triplet b = (op, n, m) such that: n ∈ N (number of inputs of the block); m ∈ N (number of outputs) and op : E n → E m (operator of the block). The n inputs and the m outputs are ordered: [i]b refers to the ith input (1 ≤ i ≤ n) and b[j] to the jth output (1 ≤ j ≤ m). For any block, we say that input i (resp. output j) exists iff i is an integer between 1 and the number of inputs of the block (resp. j, outputs). Throughout this paper, given a nonempty set E, Block(E) denotes the set of all the blocks over E. Definition 2.2: Let B be a set of blocks. A connector over B is a pair (b[i], [j]b0 ) such that: b and b0 are blocks from B; output i exists for block b and input j exists for block b0 . Definition 2.3: Let E be a nonempty set. A block diagram over E is a pair d = (B, C) such that: B is a set of blocks over E and C is a set of connectors over B.

4

b1 2 op := x2 4

4

b2

b3 op := ×

12

3 3

1 op := −

Figure 1: A block diagram in BD(R) labeled with an interpretation

Similarly to the blocks, we note BD(E) for the set of all the block diagrams over E. Figure 1 depicts three blocks over real numbers, in Block(R): block b1 has the square function as operator ; block b2 has the subtraction and block b3 has the multiplication. Connectors are represented by arrows: connector (b1 [1], [1]b2 ) from block b1 to block b2 ; (b1 [1], [1]b3 ) from b1 to b3 and (b2 [1], [2]b3 ) from b2 to b3 . The whole figure represents a block diagram over real numbers, in BD(R). B. Semantics After the block diagram syntax, it is natural to define the block diagram semantics. Definition 2.4: Let E be a nonempty set and b = (op, n, m) a block in Block(E). An interpretation I of block b is a mapping of each input i to an element in E, noted I([i]b), and each output j a mapping to an element in E, noted I(b[j]). Definition 2.5: Let E be a nonempty set and d = (B, C) a block diagram in BD(E). An interpretation I of the block diagram d is an interpretation of each block in B. Going back to the block diagram over BD(R) in Figure 1, an interpretation consists in putting a real number next to each input and output (e.g., Figure 1 where I([1]b2 ) equals 4 and I(b3 [1]) equals 12). Definition 2.6: Let E be a nonempty set, b = (op, n, m) a block in Block(E). A model I of block b is an interpretation of block b such that op(I([0]b), . . . , I([n]b)) = (I(b[0]), . . . I(b[m])) Definition 2.7: Let E be a nonempty set, d = (B, C) a block diagram in BD(E). A model I of block diagram d is such that I is an interpretation of d and: ∀b ∈ B : I is a model of block b and ∀(b[i], [j]b0 ) ∈ C : I(b[i]) = I([j]b0 ) The interpretation in Figure 1 is a model of its block diagram. Observe that it is one model among an infinity of possibilities. C. Stream Up to here, we built block diagrams over arbitrary sets. Now, we consider the set of streams where time is discrete and values are possibly different at each time step.

[0.9; 0.9; 0.9; 0.9]

f

× a [0; 0.09; 0.17; 0.24]

[0; 0.1; 0.19; 0.27]

b

+

0.1

fby

0.9 e [0; 0; 0; 0]

c [0.1; 0.19; 0.27; 0.34]

0

d [0.1; 0.1; 0.1; 0.1]

Figure 2: A block diagram on streams from BD(S(R)). In brackets, the first values of the corresponding streams, for t = 0, 1, 2, 3.

Definition 2.8 (Stream): Let D be a nonempty set. A stream s over D (also called a stream with domain D) is an infinite sequence of values from D. We name s(t) the value at time t for the stream s (t ∈ N). For any nonempty set D, we note S(D) the set of all the streams with domain D. We distinguish two categories of blocks over streams. Definition 2.9: Let D be a nonempty set and b = (op, n, m) ∈ Block(S(D)). b is a functional block iff ∃f : Dn → Dm such that ∀s1 , . . . , sn , s01 , . . . , s0m ∈ S(D): op(s1 , . . . , sn ) = (s01 , . . . , s0m ) implies the following: ∀t ∈ N, f (s1 (t), . . . , sn (t)) = (s01 (t), . . . , s0m (t)) Functional blocks can be computed independently for each time step. On the contrary, temporal blocks have time dependencies. Definition 2.10: Let D be a nonempty set and b = (op, n, m) ∈ Block(S(D)). b is a temporal block iff b is not a functional block. Among all the temporal blocks, we exhibit one: the fby block (followed by). Definition 2.11 (fby block): Let D be a nonempty set. The block fby = (op, 2, 1) in Block(S(D)) is such that: op : S(D) × S(D) → S(D) (s1 , s2 ) = s3  where s3 (t) =

s1 (0) s2 (t − 1)

if t = 0 otherwise

Block diagrams over streams can contain cycles (equivalent to loops in a classical programming language). In practice, if the loops do not involve fby, they imply an infinite computation at each time step (except for particular cases such as a null function). However, this does not happen once the cycle has at least one fby block. In the following, we assume that block diagrams contain at least one fby for each cycle. Figure 2 shows a block diagram with one cycle containing a fby. Note that temporal blocks are hatched. Blocks 0, 0.1 and 0.9 use constant operators (i.e., ∀t ∈ N : 0.9(t) = 0.9). Values for the 4 first time steps are attached to each stream. Note the delay due to the fby block.

III. S TREAM V ERIFICATION P ROBLEM Block diagrams over streams can express the semantic of real-time programs. In such cases, the programmer could be interested in the verification of some properties of his/her program. These properties can concern outputs or internal streams (i.e. output or local variables). We propose here a logical constraint model for the following problem: determine bounds of the streams of a block diagram. A. Temporal and Interval Abstractions The first step consists in abstracting the time, by considering hulls of the streams. Definition 3.1 (Temporal Abstraction): The temporal abstraction of a stream s, written s, ˙ is the set of all its values: [ s˙ = s(t) t∈N

Notice that a temporal abstraction can contain an infinity of elements. A representation in extension is thus not possible, and we are interested in interval over-approximations. In the following, we assume that D is a totally ordered set and we note ID the set of all the intervals over D. For each interval I, we note dIe its upper bound and bIc its lower bound. Definition 3.2 (Over-Approximation): Let D be a nonempty set with a total order ≤, and S a subset of D. An over-approximation in the intervals of S is an interval [S] in ID such that : [S] = {a ≤ x ≤ b | ∀s ∈ S : a ≤ s ≤ b} with a, b and x in D

2

Definition 3.3 (Minimal Over-Approximation): Let D be a nonempty set with a total order ≤, and S a subset of D. The minimal over-approximation of S, written JSK, is the smallest over-approximation under set inclusion. Proposition 3.1 (Lattice of Over-Approximations): Let D be a nonempty set together with total order ≤ and S be a subset of D. The set of all the over-approximations of S, with the set inclusion as ordering relation, is a lattice where: the join of over-approximations is given by the set union; the meet of over-approximations is given by the set intersection; the lower bound is the minimal overapproximation JSK and the upper bound is the extended set D. Corollary 3.2: Let D be a nonempty set together with a total order ≤. For all S subset of D, the minimal overapproximation exists and is unique. The proofs are classical in lattice theory. B. Constraint Model Block diagrams compute outputs from inputs. To determine over-approximations of streams for a block diagram 2 D called extended set of D is the union of D and its limits (e.g., R = R ∪ {−∞, +∞})

a b c d e f

:= := := := := :=

fby ( e , c ) ×( a , f ) +(b , d ) 0.1 0 0.9

a b c d e f

:= := := := := :=

[fby] ( e , c ) [×] ( a , f ) [+] ( b , d ) [0.1] [0] [0.9]

+

c +

fby e

a

fby

d

×

b

f

×

Figure 5: Dependency graph Figure 3: Constraint model on streams

Figure 4: Constraint model on intervals

(B, C) in BD(S(D)), we associate to each input and each output from blocks in B a variable with domain S(D). Then, for each block in B we consider its operator as a constraint linking the block outputs to the block inputs. For example, operator + from the block diagram in Figure 2 computes c as a function of b and d, yielding the constraint: c = b + d. Furthermore, for each connector in C, we add a constraint to ensure the equality of its streams. In our example, variables have already been unified (e.g., [1]+ = ∗[1] = b). Figure 3 shows the constraint model over streams corresponding to the block diagram in Figure 2. To do so, we assume that each operator in the block diagram can be translated into the constraint language. From a constraint model over stream, we consider a constraint model over intervals which contains exactly the same signatures of constraints and replaces operators over streams by its interval extension function as defined in [16] (Definition 3.4 extends the definition for streams). In such models, variables domain is not S(D) but ID . Figure 4 shows a constraint model over intervals for the diagram in Figure 3. Definition 3.4 (Interval Extension Function): Let D be a nonempty set and f be a function from S(D)n to S(D)m with n, m ∈ N. An interval extenn sion function of f , is a function [f ] from (ID ) to m (ID ) such that [f ](X1 , ..., Xn ) = Y1 , ..., Ym where Yi = [{y˙i | ∃xj ∈ Xj , y1 , ..., ym = f (x1 , ..., xn )}]. By propagating the constraints, we can compute an interval over-approximation of each stream, provided that the interval extensions of the functions are correct. Therefore, our translation of block diagrams into a constraint problem in an ad hoc language allows us to compute hulls (overapproximations) of the streams. IV. S OLVING In this paper, we analyze block diagrams as defined above, with the hypothesis that each cycle in the block-diagram contains at least one fby. It is sufficient to formulate any block diagram with finite memory. This section describes our method to solve the constraint model over intervals. A. Dependency Graph Since the initial domains can be infinite and the constraint network can contains cycles, classical constraint solvers may

fby e

fby

+

ct+1

ct

d

+ a

×

b

×

f

Figure 6: Transfer function

poorly reduce the domains. Our approach starts by a careful analysis of the variables dependencies in the generated CSP. Definition 4.1 (Dependency Graph): Let E be a nonempty set and d = (B, C) be a block diagram in BD(E). The dependency graph of d is the directed graph G = (V, A) where the set of nodes V contains all the inputs and the outputs of the blocks from B and the set of arcs A is such that: ∀(b[i], [j]b0 ) ∈ C : (b[i], [j]b0 ) ∈ A ∀b = (op, n, m) ∈ B : ([i]b, b[j]) ∈ A with (1 ≤ i ≤ n) and (1 ≤ j ≤ m) From a constraint programming point of view, these graphs are the constraints dependency graphs (where nodes are the CSP variables), except that the arcs are directed by the dependencies implied by the blocks. Figure 5 draws the dependency graph of the diagram in Figure 2. Again, temporal block arrows are hatched. Strongly connected components (scc) correspond to the loops with a fby. They are looked for on the graph for two reasons. Firstly, it splits the global problem into subproblems. Secondly, a standard algorithm from [17] returns scc ordered by their dependencies, order that we re-use for the constraint propagation. (e.g., about Figure 5, the orbital components are propagated before the central one). Finally, we propagate the constraints following the dependency graph (similarly to [18]), except for the scc which are propagated with a dedicated algorithm. B. Strongly Connected Components In this section, we present how to propagate the constraints for one strongly connected component. Our Algorithm 1, takes a set of constraints of a strongly connected component plus a domain for each variable, and returns the reduced domains after a constraint propagation. Note that the propagation of the fby blocks is left to Algorithm 2,

1: function COMPONENT S OLVER(C : Set, domain : Map) 2: return Map 3: // Remove connections to fby blocks 4: inputs, outputs : List 5: counter ← 0 : int 6: for each constraint b[i] = [j]b0 in C do 7: if b0 = fby then 8: C ← C \ {b[i] = [j]b0 } 9: inputs.INSERT([j]b0 ) 10: outputs.INSERT(b[i]) 11: counter ← counter + 1 12: end if 13: end for each 14: 15: f : (ID )counter → (ID )counter 16: f ← TRANSFER F UNCTION(C, domain, inputs, outputs) 17: approximation ← OVER A PPROXIMATION(f ) : List 18: 19: // Update domains 20: for each i from 1 to counter do 21: domain[inputs[i]] ← approximation[i] 22: domain[outputs[i]] ← approximation[i] 23: end for each 24: PROPAGATE(C, domain, inputs ∪ outputs) 25: return domain

Algorithm 1: Strongly connected component solver

presented below. Remind our assumption from Section II-C: the block diagrams always contain at least one fby per cycle. In the graph, this implies that each strongly connected components containing at least two elements contains at least one fby block/constraint. Thus, any output stream s of a fby block at time t is a function of its proper value at the previous time t − 1 (cf. Definition 2.11 introducing the fby block). Necessarily, there exists a function F such that: ∀t ∈ N : s(t + 1) = F (s(t)) and s(0) is set to the value at 0 by [0]fby. This function, called loop transfer function, can be retrieved from the component by removing the connectors linked to the inputs of fby blocks (lines 6 to 13 in Algorithm 1). Reading this new graph according to its dependencies gives the loop transfer function. Figure 6 represents the loop transfer function of the central component from the dependency graph in Figure 5. Notice that blocks in this function are only those appearing in the central component and that the fby arc has been divided into nodes ct and ct+1 . In Algorithm 1, the loop transfer function is computed by a call to TRANSFER F UNCTION line 16. The number of inputs and outputs for a loop transfer function equals the number of fby blocks in the component. In our example, the transfer function is F (X) = [0.9] × [fby]([0], X) + [0.1] where X ∈ IR . Proposition 4.1: Let D be a nonempty set and d = (B, C) be a block diagram in BD(S(D)). For all fby block b in a loop of d with F as loop transfer function. If S in ID is stable by F then S is an over-approximation for b output. Proposition 4.1 allows us to determine overapproximations and the proof is natural by construction of the loop transfer function. Algorithm 2 proposes a

function OVER A PPROXIMATION ( F : Dn → Dn ) return List state ← ”Widening” current, min, max, image : List for each i from 1 to n do current[i] ← ∅, min[i] ← ∅, max[i] ← D end for each while CONTINUE L OOPING(current, min, max) do image ← F(current) switch ← false if (state = ”Widening” and image ⊆ current) then state ← ”Narrowing”, switch ← true else if state = ”Narrowing” and image 6⊆ current then state ← ”Widening”, switch ← true end if for each i from 1 to n do if switch and state = ”Widening” then min[i] ← current[i] else if state = ”Narrowing” then max[i] ← current[i] end if current[i] = current[i] ∪ image[i] if state = ”Widening” then current[i] ← SELECT I NTERVAL B ETWEEN(current[i], max[i]) else current[i] ← SELECT I NTERVAL B ETWEEN(min[i], current[i]) end if end for each end while return max

Algorithm 2: Over-approximation random search function

method, inspired by abstract interpretation techniques, to determine sets that are stable by the loop transfer function. This algorithm may not systematically return the minimal over-approximation, but it always gives an acceptable one. We first associate each input argument of the function to a search space bounded by the intervals min[i] and max[i] which are respectively initialized with the empty set and the extended set of the considered domain. For each iteration, current[i] is selected such that it contains min[i] and it is contained in max[i] (i.e., min[i] ⊆ current[i] ⊆ max[i] is an invariant of the loop). The variable state takes its values between ”Widening” and ”Narrowing” and is initialized to ”Widening”. It switches from widening to narrowing when the interval current[i] is stable by the transfer function and switches from narrowing to widening when the contrary occurs. Functions SELECT I NTERVAL B ETWEEN and CONTINUE L OOPING are heuristics (resp. selection heuristic and loop heuristic). Table I details a trace of Algorithm 2 for the transfer function in Figure 6. Algorithm 3 presents the propagation loop following the order given by the dependency graph. V. A PPLICATION TO FAUST AND E XPERIMENTS In the end, our goal is to analyze FAUST programs to check for out-of-range audio signals. In this section, we

Variable state current image union switch min max random

Iteration

1

2

3

4

5

6

7

...

n

Widening [0; 0] [0.1; 0.1] [0; 0.1] No [0; 0] [−∞; +∞] [−10; 100]

Widening [−10; 100] [−8.9; 90.1] [−10; 100] Yes [0; 0] [−10; 100] [−3; 6]

Narrowing [−3; 6] [−2.6; 5.5] [−3; 6] No [0; 0] [−3; 6] [0; 2]

Narrowing [0; 2] [0.1; 1.9] [0; 2] No [0; 0] [0; 2] [0; 0.6]

Narrowing [0; 0.6] [0.1; 0.64] [0; 0.64] Yes [0; 0.6] [0; 2] [0; 1.2]

Widening [0; 1.2] [0.1; 1.18] [0; 1.18] Yes [0; 0.6] [0; 1.2] [0; 0.9]

Narrowing [0; 0.9] [0; 0.91] [0; 0.91] Yes [0; 0.9] [0; 1.2] ...

... ... ... ... ... ... ... ...

Any [0; 1] [0; 1] [0; 1] Yes [0; 1] [0; 1] [0; 1]

Table I: A trace table of Algorithm 2 for the transfer function in Figure 6.

1: function DOMAIN R EDUCTION((B, C) : BD(S(D)) 2: return Map 3: // Initialization 4: domain : Map 5: b : Block(S(D)) 6: for each b ∈ B do 7: for each input [i]b in b do domain[[i]b] ← D 8: for each output b[j] de b do domain[b[j]] ← D 9: end for each 10: 11: // Pretreatment 12: graph : DirectedGrah 13: graph ← DEPENDENCY G RAPH(B, C) 14: component : Set 15: components : Stack 16: components ← STRONGLY C ONNECTED C OMPONENTS(graph) 17: 18: // Body function 19: while components is not empty do 20: component ← POP(components) 21: domain ← COMPONENT S OLVER(component, domain) 22: end while 23: return domain

Algorithm 3: Global algorithm for domain reduction of block diagrams

present the application of our model to FAUST and show some experiments. A. Modelling FAUST Programs FAUST (Functional Audio Stream) is designed for realtime signal processing and synthesis. It has a particularly well defined semantics in the block diagram language [19]. After compilation, each DSP produces a C++ optimized program, which is then compiled to the desired platform. This compilation process in two steps allows a single FAUST program to run on phones, web browsers, concerts devices... For our experiments we focus on the first compilation step, producing C++ code. Inside this step, the compiler rewrites the program to a normal form by performing syntactic analysis simplifying redundant forms (e.g. x − x is replaced by 0). This normal form helps us to work on expressions with a low number of occurrences of the same variable: this is important for the CP model because continuous propagation performs poorly on constraints with multiple occurrences of variables. In the following, block diagrams are assumed to be in this normal form. Figure 8 is an

1 2 3

A = + (0.1) ; B = ∗ (0.9) ; process = A ˜ B;

Figure 7: A DSP program written in FAUST process *

0.1

0.9

+

Figure 8: A block diagram generated by the FAUST compiler

example of block diagram generated by FAUST compiling the DSP program in Figure 7. Remind that our solving method supports block diagrams only using the fby block as temporal block. Three temporal blocks exist in the FAUST language: prefix, mem and delay. Figures 9 and 10 present their semantics and propose equivalent block diagrams (i.e., with same models) with only fby blocks. The mem block is equivalent to the delay block where n equals 1. An interval extension function for fby is: [fby](A, B) = [A ∪ B]. The other FAUST operators are: common arithmetic functions; C++ imported functions (such as sin; cos, exp, ...) and relational operators.3 All these functions admit an interval extension as defined in [16] with a natural translation to constraint. Note that the equivalent expression proposed for delay block in Figure 9, has a non-negligible spatial complexity. However, the interval extension function chosen for the fby block is idempotent. Thereby, one fby is sufficient for our domain reduction problem. B. Verifying FAUST Programs We first introduce a metric to evaluate the solution quality in our experiments. 3 See http://faust.grame.fr/index.php/documentation/references for listing and description.

FAUST diagram

FAUST semantics (

n delay

b(t) = 0, si t < n b(t + n) = a(t), sinon

b

a

FAUST diagram

FAUST semantics (

a prefix

c

b

c(0) = a(0) c(t + 1) = b(t), si t > 0

Equivalent block diagram a

Equivalent block diagram

fby

c

b

0 fby

fby

b

Figure 10: FAUST prefix block

a n times

Figure 9: FAUST delay block

although it can also be a smaller interval as for the volume program). C. Results and Discussion

Definition 5.1 (Extended Metric): Let D be a nonempty set. The extended metric d between x and y in D equals 0 if x equals y and |x − y| otherwise. The extended metric for intervals X et Y in ID equals d(bXc, bY c) + d(dXe, dY e) if X is a subset of Y and +∞ otherwise. We remark that the over-approximation [S] of S a subset of E is minimal, iff the extended metric between [S] and JSK is nil. These definitions allow to manipulate infinite values. For example d(−∞, 0) returns −∞ and d(+∞, +∞), 0. A good approximation has a small distance to the minimal over-approximation. Algorithms have been implemented in C++ using the LIBIEEEP1788 library [8]. Our benchmark is composed of some pathological DSP programs, and some widely used programs from the FAUST standard library. Among the second category, SIMPLE - COUNTER is an incremental infinite loop starting at 0; FAUST- NOISE generates a random noise (i.e. sequence of random numbers) ; FAUST- OSC generates an oscillating sound wave, FAUST- FREEVERB generates a reverb on the input stream, FAUST- FIRSTORDER - FILTER is a first-order filter. The whole benchmark description, with the detailed information (DSP, block diagram and models) for each program, can be found at http://anicet.bart.free.fr/ benchmarks/ICTAI15. For each call to the solver, the looping heuristic in Algorithm 2 allows 5 backtracks without exceeding 500 interval selections by branch. About the selection heuristic, we alternate between three: choose a new lower bound between bminc and bmaxc; choose a new upper bound between dmine and dmaxe; do both. The solver has been launched 10 times for each benchmark and experimental results are presented in Figure II. The distance column contains the distance between the domain of the output, reduced by our solver, and the theorical minimal output range (which is often [−1, 1] in this benchmark, as we are dealing with correct programs computing audio processes,

The results presented in Table II show that our approach is able to significantly reduce the domains on realistic DSP instances. On the ten programs, the best approximation is found 7 times. In the three other cases, our algorithm is very close to the minimum. Analyzing these three cases, we found out that there were real variables which cannot be encoded into floating point numbers. In order to be included into the FAUST compiler, the verification step must be executed in a very short amount of time (less than a second, as an order of magnitude). Our algorithm performs well on that matter: even in rather complex programs, such as FAUST- FREEVERB or FAUSTKARPLUS 32, it is able to answer very quickly. For simpler programs, the solving time is negligible. The execution times has been considered small enough for our method to be included into the FAUST compiler. Our method is currently being implemented into the compiler. In previous works, CP has been used in test-generation or model-checking. Our results show that CP can also be a valuable technique for this new verification problem. It is worth noticing that the strength of the CP approach is twofold here: first, CP tools are defined in a generic way, which allowed us to analyze the atomic operations with offthe-shelf propagators. Second, the propagation loop in CP can naturally be combined with solving techniques (as our Algorithm 2 for the fby operator), in order to reach a better precision. This makes CP competitive with other analyzing techniques. Note that the concept of DSP is not only used in FAUST or audio processing. It appears in a lot of applications receiving and processing digital signals: modems, multimedia devices, GPS, video processing... Further works include applying our approach for other DSP languages. VI. C ONCLUSION We proposed a constraint model and a solving method for real-time audio programs verification. The experiments

program SIMPLE - ECHO SIMPLE - COUNTER SIMPLE - SINUS FAUST- NOISE FAUST- VOLUME FAUST- FIRSTORDER - FILTER FAUST- ECHO FAUST- OSC FAUST- FREEVERB FAUST- KARPLUS 32

#blocks (#fby) 4 (1) 3 (2) 4 (2) 6 (2) 8 (2) 7 (3) 16 (2) 28 (7) 237 (104) 530 (133)

time avg 1ms 11ms 10ms 1ms 21ms 22ms 14ms 31ms 510ms 690ms

distance avg < 0.001 0 0 0 0 < 0.001 0 < 0.001 0 0

#blocks evaluations min avg max 4 4 4 3, 604 3, 620 3, 635 3, 595 3, 619 3, 637 115 115 115 4, 153 4, 249 4, 318 5, 004 5, 004 5, 004 3, 156 3, 170 3, 182 7, 791 7, 871 7, 916 48, 348 48, 356 48, 360 102, 813 102, 828 102, 842

Table II: Experimental results on a benchmark of FAUST programs

show that our approach can reach very good, nearly always optimal, over-approximations in a short running time. Our method is currently being implemented into the FAUST compiler. In addition, we showed that constraint programming can handle in an elegant and natural way block diagram analyses. We plan to apply this approach to other DSPs in video, image, and sound processing. R EFERENCES [1] U. Montanari, “Networks of Constraints: Fundamental Properties and Applications to Picture Processing,” Information Science, vol. 7, no. 2, pp. 95–132, 1974. [2] F. Benhamou and W. J. Older, “Applying interval arithmetic to real, integer and Boolean constraints,” Journal of Logic Programming, vol. 32, no. 1, pp. 1–24, 1997. [3] G. Chabert and L. Jaulin, “Contractor programming,” Artificial Intelligence, vol. 173, no. 11, pp. 1079–1100, 2009. [4] P. Cousot and R. Cousot, “Abstract interpretation: a unified lattice model for static analysis of programs by construction or approximation of fixpoints,” in Conference Record of the Fourth Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages. Los Angeles, California: ACM Press, New York, NY, 1977, pp. 238–252. [5] P. Cousot and R. Cousot, “Static determination of dynamic properties of programs,” in Proceedings of the Second International Symposium on Programming. Dunod, Paris, France, 1976, pp. 106–130. [6] P. Cousot and R. Cousot, “Abstract Interpretation Frameworks,” Journal of Logic and Computation, vol. 2, no. 4, pp. 511–547, 1992.

[10] A. Lallouet, Y. C. Law, J. H. Lee, and C. F. Siu, “Constraint programming on infinite data streams,” in Proceedings of the Twenty-Second international joint conference on Artificial Intelligence-Volume Volume One. AAAI Press, 2011. [11] S. Di Alesio, S. Nejati, L. C. Briand, and A. Gotlieb, “WorstCase Scheduling of Software Tasks - A Constraint Optimization Model to Support Performance Testing,” in Principles and Practice of Constraint Programming CP 2014, Lyon, France, September 8-12, 2014. Proceedings, 2014. [12] H. Collavizza, C. Michel, O. Ponsini, and M. Rueher, “Generating Test Cases Inside Suspicious Intervals for Floating-point Number Programs,” in Proceedings of the 6th International Workshop on Constraints in Software Testing, Verification, and Analysis, ser. CSTVA 2014. New York, NY, USA: ACM, 2014, pp. 7–11. [13] T. Denmat, A. Gotlieb, and M. Ducass´e, “An abstract interpretation based combinator for modeling while loops in constraint programming,” in Principles and Practice of Constraint Programming CP 2007, Providence, RI USA, September 23-27, 2007. Proceedings, 2007, pp. 241–255. [14] M. Pelleau, A. Min´e, C. Truchet, and F. Benhamou, “A Constraint Solver Based on Abstract Domains,” in Verification, Model Checking, and Abstract Interpretation, 14th International Conference, VMCAI 2013, Rome, Italy, January 20-22, 2013. Proceedings, 2013, pp. 434–454. [15] O. Ponsini, C. Michel, and M. Rueher, “Refining Abstract Interpretation Based Value Analysis with Constraint Programming Techniques,” in Principles and Practice of Constraint Programming CP 2012, Qu´ebec City, QC, Canada, October 8-12, 2012. Proceedings, 2012, pp. 593–607. [16] R. Edgar Moore, Interval Analysis. Prentice-Hall, Englewood Cliffs N. J., 1966.

[7] Y. Orlarey, D. Fober, and S. Letz, “Syntactical and semantical aspects of Faust,” Soft Computing, vol. 8, no. 9, pp. 623–632, 2004.

[17] M. Sharir, “A strong-connectivity algorithm and its applications in data flow analysis,” Computers & Mathematics with Applications, vol. 7, no. 1, pp. 67–72, 1981.

[8] M. Nehmeier, “libieeep1788: A C++ Implementation of the IEEE interval standard P1788,” in Norbert Wiener in the 21st Century (21CW), 2014 IEEE Conference on, June 2014.

[18] R. Dechter and J. Pearl, “The anatomy of easy problems: A constraint-satisfaction formulation,” in Proceedings of the 9th International Joint Conference on Artificial Intelligence Volume 2, ser. IJCAI’85, 1985, pp. 1066–1072.

[9] J. Lee and J. Lee, “Towards Practical Infinite Stream Constraint Programming: Applications and Implementation,” in Principles and Practice of Constraint Programming, B. O’Sullivan, Ed. Springer International Publishing, 2014.

[19] Y. Orlarey, D. Fober, and S. Letz, “An Algebra for Block Diagram Languages,” in International Computer Music Conference, 2002.