Bounded Synthesis of Reactive Programs
Abstract
Most algorithms for the synthesis of reactive systems focus on the construction of finitestate machines rather than actual programs. This often leads to badly structured, unreadable code. In this paper, we present a bounded synthesis approach that automatically constructs, from a given specification in lineartime temporal logic (LTL), a program in Madhusudan’s simple imperative language for reactive programs. We develop and compare two principal approaches for the reduction of the synthesis problem to a Boolean constraint satisfaction problem. The first reduction is based on a generalization of bounded synthesis to twoway alternating automata, the second reduction is based on a direct encoding of the program syntax in the constraint system. We report on preliminary experience with a prototype implementation, which indicates that the direct encoding outperforms the automata approach.
1 Introduction
In reactive synthesis, we automatically construct a reactive system, such as the controller of a cyberphysical system, that is guaranteed to satisfy a given specification. The study of the synthesis problem, known also as Church’s problem [2], dates back to the 1950s and has, especially in recent years, attracted a lot of attention from both theory and practice. There is a growing number of both tools (cf. [3, 4, 5, 6]) and success stories, such as the synthesis of an arbiter for the AMBA AHB bus, an open industrial standard for the onchip communication and management of functional blocks in systemonachip (SoC) designs [7].
The practical use of the synthesis tools has, however, so far been limited. A serious criticism is that, compared to code produced by a human programmer, the code produced by the currently available synthesis tools is usually badly structured and, quite simply, unreadable. The reason is that the synthesis tools do not actually synthesize programs, but rather much simpler computational models, such as finite state machines. As a result, the synthesized code lacks control structures, such as while loops, and symbolic operations on program variables: everything is flattened out into a huge state graph.
A significant step towards better implementations has been the bounded synthesis [8] approach, where the number of states of the synthesized implementation is bounded by a constant. This can be used to construct finite state machines with a minimal number of states. Bounded synthesis has also been extended with other structural measures, such as the number of cycles [9]. Bounded synthesis reduces the synthesis problem to a constraint satisfaction problem: the existence of an implementation of bounded size is expressed as a set of Boolean constraints, which can subsequently be solved by a SAT or QBF solver [10]. Bounded synthesis has proven highly effective in finding finite state machines with a simple structure. However, existing methods based on bounded synthesis do not make use of syntactical program constructs like loops or variables. The situation is different in the synthesis of sequential programs, where programs have long been studied as the target of synthesis algorithms [11, 12, 13, 14, 15]. In particular, in syntaxguided synthesis [11], the output of the synthesis algorithm is constrained to programs whose syntax conforms to a given grammar. A first theoretical step in this direction for reactive systems was proposed by Madhusudan [16]. Madhusudan defines a small imperative programming language and shows that the existence of a program in this language with a fixed set of Boolean variables is decidable. For this purpose, the specification is translated into an alternating twoway tree automaton that reads in the syntax tree of a program, simulates its behavior, and accepts all programs whose behavior satisfies the specification. Because the set of variables is fixed in advance, the approach can be used to synthesize programs with a minimal number of variables. However, unlike bounded synthesis, this does not lead to programs that are minimial in other ways, such as the number of states or cycles.
In this paper, we present the first bounded synthesis approach for reactive programs. As in standard bounded synthesis [8], we reduce the synthesis problem to a constraint satisfaction problem. The challenge is to find a constraint system that encodes the existence of a program that satisfies the specification, and that, at the same time, can be solved efficiently. We develop and compare two principal methods. The first method is inspired by Madhusudan’s construction in that we also build a twoway tree automaton that recognizes the correct programs. The key difficulty here is that the standard bounded synthesis approach does not work with twoway automata, let alone the alternating twoway automata produced in Madhusudan’s construction. We first give a new automata construction that produces universal, instead of alternating, twoway automata. We then generalize bounded synthesis to work on arbitrary graphs, including the run graphs of twoway automata. The second method follows the original bounded synthesis approach more closely. Rather than simulating the execution of the program in the automaton, we encode the existence of both the program and its run graph in the constraint system. The correctness of the synthesized program is ensured, as in the original approach, with a universal (oneway) automaton derived from the specification. Both methods allow us to compute programs that satisfy the given specification and that are minimal in measures such as the size of the program. The two approaches compute the exact same reactive programs, but differ, conceptually, in how much work is done via an automatatheoretic construction vs. in the constraint solving. In the first approach, the verification of the synthesized program is done by the automaton, in the second approach by the constraint solving. Which approach is better? While no method has a clear theoretical advantage over the other, our experiments with a prototype implementation indicate a strong advantage for the second approach.
2 Preliminaries
We denote the Boolean values by . The set of nonnegative integers is denoted by and for the set is denoted by . An alphabet is a nonempty finite set of symbols. The elements of an alphabet are called letters. A infinite word over an alphabet is a infinite concatenation of letters of . The set of infinite words is denoted by . With we access the th letter of the word. For an infinite word we define with Inf the set of states that appear infinitely often in . A subset of is a language over infinite words.
2.1 Implementations
Implementations are arbitrary inputdeterministic reactive systems. We fix the finite input and output alphabet and , respectively. A Mealy machine is a tuple where is an inputalphabet, is an outputalphabet, is a finite set of states, is an initial state, is a transition function and is an output function. A system path over an infinite input sequence is the sequence such that . The thereby produced infinite output sequence is defined as , where every element has to match the output function, i.e., . We say a Mealy machine produces a word , iff the output is produced for input . We refer to the set of all producible words as the language of , denoted by .
A more succinct representation of implementations are programs. The programs we are working with are imperative reactive programs over a fixed set of Boolean variables and fixed input/output aritys /. Our approach builds upon [16] and we use the same syntax and semantics. Let be a variable and both and be vectors over multiple variables of size and , respectively. The syntax is defined with the following grammar
::=  skip b := input output  
if() then {} else {} while(){}  
::=  b tt ff ( () 
The semantics are the natural one. Our programs start with an initial variable valuation we define to be for all variables. The program then interacts with the environment by the means of input and output statements, i.e., for a vector over Boolean variables the statement \enquoteinput takes an input in from the environment and updates the values of . The statement \enquoteoutput outputs the values stored in , that is an output in . Therefor a program with input/output arity requires at least many variables, i.e., . Between two input and output statements the program can internally do any number of steps and manipulate the variables using assignments, conditionals and loops. Note that programs are inputdeterministic, i.e., a program maps an infinite input sequence to an infinite output sequence and we say a program can produce a word , iff it maps to . We define the language of , denoted by , as the set of all producible words. We assume programs to alternate between input and output statements.
We represent our programs as labeled binary trees, i.e., a tuple where is a finite and prefix closed set of nodes and is a labeling function. Based on the defined syntax, we fix the set of labels as
.
We refer to labeled binary trees as program trees. If a node has only one subtree we define it to be a the left subtree. Note that our program trees do therefore not contain nodes with only a right subtree. For example, Fig. 2 depicts an arbitrary program and Fig. 2 the corresponding program tree.
We express the current variable valuation as a function . We update variables with new values using the following notation:
2.2 Automata
We define alternating automata over infinite words as usual, that is a tuple where is a finite alphabet, is a finite set of states, is an initial state, is a transition function and is an acceptance condition.
The Büchi acceptance condition on a set of states is defined as and is called the set of accepting states. The coBüchi acceptance condition on a set of states is defined as , where is called the set of rejecting states. To express combinations of Büchi and coBüchi expressions we use the Streett acceptance condition. Formally, on a set of tuples is defined as . A run with a Streett condition is intuitively accepted, iff for all tuples , the set is hit only finitely often or the set is hit infinitely often.
Twoway alternating tree automata are tuple , where is an input alphabet, is a finite set of states, is an initial state, is an acceptance condition, and are transition functions of type
, for .
We introduce as a function to map states and directions to move in, to the reached states and the matching incoming directions.
We consider specifications given in linear timetemporal logic (LTL). Such specifications can be translated into nondeterministic Büchi automata or dually into an universal coBüchi automata as shown in [17]. For an arbitrary specification we denote by and the corresponding nondeterministic Büchi and universal coBüchi automaton, respectively.
3 Automata Construction
We have already argued that programs, as a more succinct representation of implementations, are highly desirable. However, in contrast to Mealy machines, which only dependent on the current state and map an input to a corresponding output, in programs such a direct mapping is not possible. Instead, programs need to be simulated, variables to be altered, expressions to be evaluated and an output statement to be traversed until we produce the corresponding output to the received input. These steps not only depend on the current position in the program but additionally also on the valuation of all variables.
We build upon Madhusudans reactive program synthesis approach [16] were program synthesis is solved by means of twoway alternating Büchi tree automata walking up and down over program trees while keeping track of the current valuation and the state of a given Büchi specification automaton, which is simulated by the input/output produced by traversing the program tree. The automaton accepts a program tree whenever the simulated specification automaton accepts the provided input/output. The constructed automaton, we will further refer to as , is intersected with two other constructed automata which enforce syntactically correctness and reactivity of the synthesized program, respectively. Then a reactive and syntactically correct program is synthesized by means of an emptiness check of the obtained automaton, involving an exponential blowup to eliminate twowayness and alternation.
3.1 Twoway Universal CoBüchi Tree Automaton
We construct a twoway nondeterministic Büchi tree automaton that is equivalent to by using deterministic evaluation of Boolean expressions. We construct without an exponential blowup in the state space. We then complement into a twoway universal coBüchi tree automaton convenient for the bounded synthesis approach.
The twoway alternating Büchi tree automaton uses universal choices only in relation to Boolean expression evaluation. For example, for if, while and statements a Boolean evaluation is needed. In this cases it nondeterministically guesses whether the expression evaluates to or and then universally sends one copy into the Boolean expression, which evaluates to iff the expression evaluates to the expected value, and one copy to continue the corresponding normal execution. The copy evaluating the Boolean expression walks only downwards and since the subtree corresponding to the Boolean expression is finite, this copy terminates to either or after finitely many steps. Instead of using both nondeterministic and universal choices, we evaluate the Boolean subtree deterministically in finitely many steps and then continue the normal execution based on the result of the evaluation.
Note that we not only remove all universal choices but additionally all unnecessary sources of nondeterminism. Therefore, besides traversing input and outputlabels, that introduce unavoidable nondeterminism, our program simulation is deterministic.
Our automaton with the set of states
and initial state , is defined with the transitions shown in Fig. 3, where is a variable valuation, the state of the simulated specification automaton, the last received input, a flag to ensure alternation between inputs and outputs, the result of a Boolean evaluation and a flag for the Büchi condition, which ensures that the specification automaton is simulated for infinite steps and is only set to for a single simulation step after an output statement. We express states corresponding to Boolean evaluations and program execution as and , respectively.
The notation reads as follows: If the automaton enters a node with one of the black incoming edges, it can move in the direction of the black outgoing edges, while updating his state corresponding to the annotated update expression, depicted by an enclosing rectangle. Additionally, the automaton needs to fulfill the conditions annotated to the edges it traverses. To express nondeterminism we use sets of update expressions, such that each expression represents one possible successor. All state values not contained in the update expression stay the same, except which is set to . When changing from Boolean evaluation to program execution, we copy , , , and vice versa.
The set of accepting states is defined as
A formal construction of is given in Section A.1.3. Note that behaves similar to during normal execution and that only Boolean evaluation was altered. Therefore, the state spaces of the automata only differ in the states corresponding to Boolean evaluation and especially the sets of accepting states and are equivalent. Therefore, we can prove the equivalence by showing that both automata visit the same sequences of accepting states and thus accept the same program trees.
Theorem 3.1 (Section a.1)
We now complement the constructed twoway nondeterministic Büchi automaton into a twoway universal coBüchi automaton. From this point onwards, we refer with to the twoway universal coBüchi automaton.
Since accepts precisely the programs that fail the specification and interact infinitely often with the environment, the complement now only accepts programs that do satisfy the specification or interact finitely often with the environment. We fix the remaining misbehavior by enforcing syntactical correctness and reactiveness.
3.2 Guarantee Syntactical Correctness
Due to the fact that was designed to correctly simulate programs of our defined syntax and transitions were only defined for syntaxvalid statements, implicitly rejects programs that are syntactically invalid. But such programs are only then rejected when their syntactically incorrect statements are traversed in the simulation, therefore does not check for syntactically correct subtrees that are unreachable. It is now arguable whether the syntax check is necessary in practice. One could expect programs to be syntactically correct in total and this expectation is in general wellargued. On the other hand, we do perform bounded synthesis, i.e., we search for implementations with a bound on the implementation size and then increment this bound until a valid implementation is found. It is easy to see that programs with unreachable parts can be represented by smaller programs with the same behavior simply by removing unreachable statements. Therefore, with an incremental search one first finds the smallest and thus syntactically correct programs.
3.3 Guarantee Reactiveness
It now remains to guarantee reactiveness of the programs accepted by . For that purpose, we introduce a twoway universal Büchi automaton , which only accepts program trees that are reactive. This automaton is designed with the exact same states and transitions as but with another acceptance condition. The intersection of and then yields a twoway universal Streett automaton . We construct with the set of accepting states:
accepts a program tree, iff it produces infinitely many outputs on all possible executions. Due to the alternation between input and output statements the program reacts infinitely often with its environment, i.e., it is reactive.
Formally, is the tuple , where
Lemma 1
Proof
Besides the acceptance condition, all three automata are equivalent. The tuples of the Streett condition and express the coBüchi and Büchi condition of and , respectively. ∎
We capture the complete construction by the following theorem.
Theorem 3.2
Let be a finite set of Boolean variables and a specification given as LTLformula. The constructed twoway universal Streett automaton accepts program trees over that satisfy the specification.
4 Bounded Synthesis
In this section, we generalize the bounded synthesis approach towards arbitrary universal automata and then apply it to the constructed twoway automaton to synthesize bounded programs.
We fix to be a finite set of states. A run graph is a tuple , where is a finite set of vertices, is an initial vertex, is a set of directed edges and is a labeling function. A path is contained in , denoted by , iff and , i.e., a path in the graph starting in the initial vertex. We denote with the application of on every node in the path, i.e., a projection to an infinite sequence of states. We call a vertex unreachable, iff there exists no path containing . Let be an acceptance condition. We say satisfies , iff every path of satisfies the acceptance condition, i.e., .
Run graphs are used to express all possible runs of a universal automaton on some implementation. This is usually done for universal word automata on Mealy machines, but we need a generalized version to later utilize it for twoway universal tree automata on program trees. Let . We define a run graph of a universal word automaton on a Mealy machine as an instantiation of the given definition, where

,

,

and 
.
Since the run graph contains all infinite runs of on words producible by , accepts , iff all runs in are accepting, i.e., satisfies .
For some bound we denote by . For a run graph and a bound a bounded annotation function on is a function . An annotation comparison relation of arity is a family of relations . We refer to as basic comparison relations for . We denote the arity with . We write for and for comparison relations of arity we omit the index.
We say a path satisfies a comparison relation with arity , denoted by , iff for every basic comparison relation there exists an annotation function that annotates every node with a value such that the annotated number for all consecutive nodes in the path satisfy the basic comparison relation, i.e., For an acceptance condition we say a comparison relation expresses , iff all paths in satisfy the relation if and only if the path satisfies the acceptance condition, i.e., A bounded annotation function on is valid for a basic annotation comparison relation , iff
We use the following annotation comparison relations to express Büchi, coBüchi and Streett acceptance conditions.

Let and . Then is defined as

Let and . Then is defined as

Let and . Then is defined as
Note that and .
Theorem 4.1 ([8, 18])
Let be a set, the acceptance condition of be expressed by with , a bound and the run graph of on .
If and only if, there exists a valid bounded annotation function on for each basic comparison relation , then satisfies .
4.1 General Bounded Synthesis
In Theorem 4.1 we saw that the acceptance of a Mealy machine by a universal automata can be expressed by the existence of an annotation comparison relation. To do the same for twoway automata on program trees, we generalize this theorem towards arbitrary run graphs.
Let be a twoway universal tree automaton and a program tree. We define the run graph of on as , where

,

,

and 
.
For the generalized encoding, we use the same construction for the annotation comparison relation as presented in [18] for Street acceptance conditions, which conveniently suffices for the general run graphs. Büchi and coBüchi then follow as special cases.
Lemma 2 (Section a.2)
For a Streett acceptance condition with set of tuples of states and a run graph :
If satisfies , then there exists a valid bounded annotation function for each basic comparison relation in .
Theorem 4.2
Let be a run graph, a Büchi, coBüchi or Streett acceptance condition expressed by the relation for .
There exists a valid bounded annotation function on for each basic comparison relation , if and only if satisfies .
Proof
Let , , with arity and be given and be a valid bounded annotation comparison relation on for for all . Let be an arbitrary path in and . Since is a valid annotation function, holds and therefore . Since expresses it follows that , i.e., satisfies .
Lemma 2. ∎
4.2 General Encoding
We showed that the run graph satisfies an acceptance condition , iff the implementation is accepted by the automaton. We also proved that the satisfaction of by a run graph can be expressed by the existence of valid annotation functions.
We encode these constraints in SAT. The valid implementation can then be extracted from the satisfied encoding. Note that in our definition of program trees the structure was implicitly expressed by the nodes and for the encoding we need to express them explicitly. Therefore, the structure of the tree is encoded with successor functions and , expressing the left and right child of a node, respectively. We encode the program tree and the annotation function as uninterpreted functions as explained in the following. We introduce the following variables for arbitrary twoway automata , program trees , bounds and annotation comparison relations :

encodes label of with many variables, notated as

iff has left child (implicitly the next program state )

encodes right the child of with many variables

iff state is reachable in the run graph

encodes the th annotation of state with many variables. We omit the index in the encoding
The SAT formula consists of the following constraints:

The initial state is reachable and all annotations fulfill the given bound:

Bounded synthesis encoding
returns a list of pairs , where the formula enforces the tree structure needed to reach .
The encoding checks whether universal properties in the run graph hold. Note that we need to additionally forbid walking up from the root node, which is omitted here.
Theorem 4.3
Given a twoway universal tree automaton with a Büchi, coBüchi or Streett acceptance condition expressed by and a bound . The constraint system is satisfiable, iff there is a program tree with size that is accepted by .
Proof
Let be accepted by , then with Theorem 4.2 there exists a valid annotation function on for each . Let be represented by and be for all reachable states in the run graph . Then is satisfied.
Let be satisfied. Then there exists a valid annotation function encoded by for each (set for all unreachable states , i.e., where is ) that satisfies the encoding. With Theorem 4.2 the acceptance of by follows. ∎
Utilizing this theorem, we now can by means of the encoding synthesize program trees accepted by , i.e., precisely those program trees, which correspond to reactive programs that satisfy the given specification the automaton was constructed with.
Corollary 1
The SAT encoding is satisfiable, if and only if there exists a program tree with size accepted by .
Size of construction
The automaton can be constructed of size , i.e., for a fixed set of Boolean variables the automaton is linear in the size of the specification automaton or exponential in the size of the specification formula. The constructed constraint system is of size with many variables, where . Note that grows polynomial in the number of variables for fixed input/output arities.
5 TwoWayless Encoding
Next, we sketch the second encoding that avoids the detour via universal twoway automata. To this end, we alter the construction in that input and outputlabels collapse to a single InOutlabel with semantics as follows
where we use output variables and input variables that correspond to inputs and outputs of the system, respectively. In a nutshell, our new encoding consists of four parts:

The first part guesses the program and ensures syntactical correctness.

The second part simulates the program for every possible input from every reachable InOutlabeled state until it again reaches the next InOutlabeled state. Note that every such simulation trace is deterministic once the input, read at the initial InOutlabeled state, has been fixed.

The third part extracts a simplified transition structure from the resulting execution graph, that consists of direct input labeled transitions from one InOutlabeled state to the next one and output labeled states.

In the last part, this structure is then verified by a run graph construction that must satisfy the specification, given as universal coBüchi automaton. To this end, we couple inputs on the edges with the outputs of the successor state to preserve the Mealy semantics of the program.
The first part utilizes a similar structure as used for the previous encoding and thus is skipped for convenience here. To simulate the program in the second part, we introduce the notion of a valuation , where
captures the current program state, the current values of all noninput variables, the current direction, and the result of the evaluation of the last Boolean expression, respectively. The simulation of the program is then expressed by a finite execution graph, in which, after fixing a inputs , every valuation points to a successor valuation. This successor valuation is unique, except for InOutlabeled states, whose successor depends on the next input to be read. The deterministic evaluation follows from the rules of Figure 3 and selects a unique successor for every configuration, accordingly.
In part three, this expression graph then is compressed into a simplified transition structure. To this end, we need for every input and InOutlabeled starting valuation, the target InOutlabeled valuation that is reached as a result of the deterministic evaluation. In other words, we require to find a shortcut from every such valuation to the next one. We use an inductive chain of constraints to determine this shortcut efficiently. Remember that we only know the unique successor of every valuation which only allows to make one step forward at a time. Hence, we can store for every valuation and input a second shortcut successor, using an additional set of variables, constrainted as follows: if the evaluated successor is InOutlabeled, then the shortcut successor must be the same as the evaluated one. Otherwise, it is the same as the shortcut successor of the successor valuation, leading to the desired inductive definition. Furthermore, to ensure a proper induction base, we use an additional ranking on the valuations that bounds the number of steps between two InOut labeled valuations. This annotation is realized in a similar fashion as in the previously presented encoding.
With these shortcuts at hand, we then can extract the simplified transition structure, which is verified using a standard run graph encoding as used for classical bounded synthesis. Furthermore, we use an overapproximation to bound the size of the struture and use a reachability annotation that allows the solver to reduce the constraints to those parts as required by the selected solution. The size can, however, also be bound using an explicit bound that is set manually.
Using this separation into four independent steps allows to keep the encoding compact in size, and results in the previously promised performance improvements presented in the next section.
6 Experimental Results
specification  states  additional  twoway  twowayless  

variables  encoding  encoding  
in out  6  0  16  00m16s  00m02s 
in out  9  1  64  11m29s  08m34s 
latch  10  0  64  120m  08m07s 
2bit arbiter  10  0  128  66m48s  14m18s 
Table 1 compares the general encoding of Section 4.1 and the twowayless encoding of Section 5 on a selection of standard benchmarks. The table contains the of number of states of the program’s syntax tree, the number of additional variables, i.e., variables that are not designated to handle inputs and outputs, the size of the twoway universal Streett automaton, created for the general encoding, and the solving times for both encodings. Table 2 shows the results in terms of the synthesized program trees for the twowayless encoding. The experiments indicate a strong advantage of the second approach.
in out  in out  latch  2bit arbiter 

while(tt) { out = in; InOut }  while(tt) { out = var; var = in; InOut }  while (tt) { if (upd) { out = in } else { skip }; InOut }  while (tt) { g0 = g1; g1 = not g1; InOut } 
7 Conclusions
We introduced a generalized approach to bounded synthesis that is applicable whenever all possible runs of a universal automaton on the possibly produced input/output words of an inputdeterministic implementation can be expressed by a run graph. The acceptance of an implementation can then be expressed by the existence of valid annotation functions for an annotation comparison relation that expresses the acceptance of the automaton for Büchi, coBüchi and Streett acceptance conditions. The existence of valid annotation functions for a run graph is encoded as a SAT query that is satisfiable if and only if there exists an implementation satisfying a given bound that is accepted by the automaton.
For LTL specifications, we constructed a twoway universal Streett automaton which accepts reactive programs that satisfy the specification. We then constructed a run graph that represents all possible runs and applied the generalized bounded synthesis approach. Next, we constructed a SAT query that guesses a reactive program of bounded size as well as valid annotation functions that witnesses the correctness of the synthesized program.
Finally, we merged the previous transformations into an extended encoding that simulates the program direclty via the constraint solver. We evaluated both encodings with the clear result that the encoding avoiding the explicit run graph construction for twoway automata wins in the evaluation.
Appendix A Appendix
a.1 Equivalence of and
To prove the equivalence, i.e., , we need the formal definition of acceptance of trees by twoway tree automata and of the twoway automata and . We fix the specification to be given as a nondeterministic Büchi word automaton .
Acceptance of twoway tree automata
The acceptance is defined over run trees as follows. A run of a twoway alternating tree automaton on a program tree is an infinite labeled binary tree , where is a labeling function, which labels are tuples that contain the current state of the automaton and program tree as well as the direction it came from. For it holds that

, and

with and
Let be a set that satisfies . Then and with .
Twoway alternating Büchi tree automaton
The constructed twoway alternating Büchi automaton over the alphabet with the set of states ,
and initial state , is defined with the following transitions, where , , , , and .

Transitions to evaluate Boolean expressions:


Transitions to evaluate non I/O statements:
