We consider an extension of logic programs, called -programs, that can be used to define predicates over infinite lists. -programs allow us to specify properties of the infinite behavior of reactive systems and, in general, properties of infinite sequences of events. The semantics of -programs is an extension of the perfect model semantics. We present variants of the familiar unfold/fold rules which can be used for transforming -programs. We show that these new rules are correct, that is, their application preserves the perfect model semantics. Then we outline a general methodology based on program transformation for verifying properties of -programs. We demonstrate the power of our transformation-based verification methodology by proving some properties of Büchi automata and -regular languages.
KEYWORDS: Program Transformation, Program Verification, Infinite Lists.
Transformations of Logic Programs on Infinite
Lists] Transformations of Logic Programs on
A. Pettorossi, M. Proietti, and V. Senni]
DISP, University of Rome Tor Vergata, Via del Politecnico 1, I-00133 Rome, Italy
and MAURIZIO PROIETTI
IASI-CNR, Viale Manzoni 30, I-00185 Rome, Italy
and VALERIO SENNI
DISP, University of Rome Tor Vergata, Via del Politecnico 1, I-00133 Rome, Italy
[–LABEL:lastpage \volumenn (n): \jdatemonth 2010 2010
The problem of specifying and verifying properties of reactive systems, such as protocols and concurrent systems, has received much attention over the past fifty years or so. The main peculiarity of reactive systems is that they perform nonterminating computations and, in order to specify and verify the properties of these computations, various formalisms dealing with infinite sequences of events have been proposed. Among these we would like to mention: (i) Büchi automata and other classes of finite automata on infinite sequences [Thomas (1990)], (ii) -languages [Staiger (1997)], and (iii) various temporal and modal logics (see [Clarke et al. (1999)] for a brief overview of these logics).
Also logic programming has been proposed as a formalism for specifying computations over infinite structures, such as infinite lists or infinite trees (see, for instance, [Colmerauer (1982), Lloyd (1987), Simon et al. (2006), Min and Gupta (2010)]). One advantage of using logic programming languages is that they are general purpose languages and, together with a model-theoretic semantics, they also have an operational semantics. Thus, logic programs over infinite structures can be used for specifying infinite computations and, in fact, providing executable specifications for them. However, very few techniques which use logic programs over infinite structures, have been proposed in the literature for verifying properties of infinite computations. We are aware only of a recent work presented in [Gupta et al. (2007)], which is based on coinductive logic programming, that is, a logic programming language whose semantics is based on greatest models.
In this paper our aim is to develop a methodology based on the familiar unfold/fold transformation rules [Burstall and Darlington (1977), Tamaki and Sato (1984)] for reasoning about infinite structures and verifying properties of programs over such structures. In order to do so, we do not introduce a new programming language, but we consider a simple extension of logic programming on finite terms by introducing the class of the so-called -programs, which are logic programs on infinite lists. Similarly to the case of logic programs, for the class of locally stratified -programs we define the perfect model semantics (see [Apt and Bol (1994)] for a survey on negation in logic programming).
We extend to -programs the transformation rules for locally stratified programs presented in [Fioravanti et al. (2004), Pettorossi and Proietti (2000), Roychoudhury et al. (2002), Seki (1991), Seki (2010)] and, in particular: (i) we introduce an instantiation rule which is specific for programs on infinite lists, (ii) we weaken the applicability conditions for the negative unfolding rule, and (iii) we consider a more powerful negative folding rule (see Sections 3 and 4 for more details). We prove that these rules preserve the perfect model semantics of -programs.
Then we extend to -programs the transformation-based methodology for verifying properties of programs presented in [Pettorossi and Proietti (2000)]. We demonstrate the power of our verification methodology through some examples. In particular, we prove: (i) the non-emptiness of the language recognized by a Büchi automaton, and (ii) the containment between languages denoted by -regular expressions.
The paper is structured as follows. In Section 2 we introduce the class of -programs and we define the perfect model semantics for locally stratified -programs. In Section 3 we present the transformation rules and in Section 4 we prove that they preserve the semantics of -programs. In Section 5 we present the transformation-based verification method and we see it in action in some examples. Finally, in Section 6 we discuss related work in the area of program transformation and program verification.
2 Programs on Infinite Lists
Let us consider a first order language given by a set Var of variables, a set Fun of function symbols, and a set Pred of predicate symbols. We assume that Fun includes: (i) a finite, non-empty set of constants, (ii) the constructor of the infinite lists of elements of , and (iii) at least one constant not in . Thus, is an infinite list whose head is and whose tail is the infinite list . Let denote the set of the infinite lists of elements of .
We assume that is a typed language [Lloyd (1987)] with three basic types: (i) fterm, which is the type of the finite terms, (ii) elem, which is the type of the constants in , and (iii) ilist, which is the type of the infinite lists of . Every function symbol in Fun, with arity , has type , where occurs times to the left of . The function symbol has type . A predicate symbol of arity in Pred has type of the form , where . For every term (or formula) , we denote by the set of variables occurring in .
An -clause is a formula of the form , with , where is an atom and are (positive or negative) literals, constructed as usual from symbols in the typed language , with the following extra condition: every predicate in has, among its arguments, at most one argument of type . This condition makes it easier to prove the correctness of the positive and negative unfolding rules (see Section 3 for further details). We denote by true the empty conjunction of literals. An -program is a set of -clauses.
Let HU be the Herbrand universe constructed from the set Fun of function symbols. An interpretation for our typed language , called an -interpretation, is a function such that: (i) assigns to the types fterm, elem, and ilist, respectively, the sets HU, , and (which by our assumptions are non-empty), (ii) assigns to the function symbol , the function such that, for any element , for any infinite list , is the infinite list , (iii) is an Herbrand interpretation for all function symbols in , and (iv) assigns to every -ary predicate Pred of type , a relation on , where, for , is either HU or or , if is either or or , respectively. We say that an -interpretation is an -model of an -program if for every clause we have that , where vars.
A valuation is a function Var HU such that: (i) if has type then , (ii) if has type then , and (iii) if has type then . The valuation function can be extended to any term , or literal , or clause , by making the function act on the variables occurring in , or , or . We extend the notion of Herbrand base [Lloyd (1987)] to -programs by defining it to be the set is an -ary predicate symbol in Pred and is a valuation. Thus, any -interpretation can be identified with a subset of .
A local stratification is a function : , where is the set of countable ordinals. Given , we define . Given an -clause of the form and a local stratification , we say that is locally stratified w.r.t. if, for , for every valuation , . An -program is locally stratified w.r.t. , or is a local stratification for , if every clause in is locally stratified w.r.t. . An -program is locally stratified if there exists a local stratification such that is locally stratified w.r.t. .
A level mapping is a function . A level mapping is extended to literals as follows: for any literal having predicate , if is a positive literal, then and, if is a negative literal then . An -clause of the form is stratified w.r.t. if, for , . An -program is stratified if there exists a level mapping such that all clauses of are stratified w.r.t. [Lloyd (1987)]. Clearly, every stratified -program is a locally stratified -program. Similarly to the case of logic programs on finite terms, for every locally stratified -program , we can construct a unique perfect -model (or perfect model, for short) denoted by (see [Apt and Bol (1994)] for the case of logic programs on finite terms). Now we present an example of this construction.
Let: (i) be the set of constants of type elem, (ii) be a variable of type elem, and (iii) be a variable of type ilist. Let and be predicates of type ilist. Let us consider the following -program :
We have that: (i) holds iff is an infinite list of ’s and (ii) holds iff at least one occurs in . Program is stratified w.r.t. the level mapping such that and . The perfect model is constructed by starting from the ground atoms of level 0 (i.e., those with predicate ). We have that, for all , iff , that is, iff . Then, we consider the ground atoms of level 1 (i.e., those with predicate ). For all , iff . Thus, iff .
3 Transformation Rules
Given an -program , a transformation sequence is a sequence , with , of -programs constructed as follows. Suppose that we have constructed a sequence , for . Then, the next program in the sequence is derived from program by applying one of the following transformation rules R1–R7.
First we have the definition introduction rule which allows us to introduce a new predicate definition.
R1. Definition Introduction. Let us consider () clauses of the form:
where: (i) newp is a predicate symbol not occurring in , (ii) are distinct variables occurring in , (iii) none of the ’s is the empty conjunction of literals, and (iv) every predicate symbol occurring in also occurs in . The set of clauses is said to be the definition of newp.
By definition introduction from program we derive the new program . For , Defs denotes the set of clauses introduced by the definition rule during the transformation sequence . In particular, Defs.
In the following instantiation rule we assume that the set of constants of type elem in the language is the finite set .
R2. Instantiation. Let : be a clause in program and be a variable of type ilist occurring in . By instantiation of in , we get the clauses:
: , …, :
and we say that clauses are derived from . From we derive the new program .
The unfolding rule consists in replacing an atom occurring in the body of a clause by its definition in . We present two unfolding rules: (1) the positive unfolding, and (2) the negative unfolding. They correspond, respectively, to the case where or occurs in the body of the clause to be unfolded.
R3. Positive Unfolding. Let be a clause in program and let be a variant of without variables in common with . Let
be all clauses of program such that, for , is unifiable with , with most general unifier .
By unfolding w.r.t. we get the clauses , where for , is , and we say that clauses are derived from . From we derive the new program .
In rule R3, and also in the following rule R4, the most general unifier can be computed by using a unification algorithm for finite terms (see, for instance, [Lloyd (1987)]). Note that this is correct, even in the presence on infinite terms, because in any -program each predicate has at most one argument of type ilist. On the contrary, if predicates may have more than one argument of type ilist, in the unfolding rule it is necessary to use a unification algorithm for infinite structures [Colmerauer (1982)]. For reasons of simplicity, here we do not make that extension of the unfolding rule and we stick to our assumption that every predicate has at most one argument of type ilist.
The existential variables of a clause are the variables occurring in the body of and not in its head.
R4. Negative Unfolding. Let : be a clause in program and let be a variant of without variables in common with . Let
be all clauses of program , such that, for , is unifiable with , with most general unifier . Assume that: (1) , that is, for , is an instance of , (2) for , has no existential variables, and (3) from we get a logically equivalent disjunction of conjunctions of literals, with , by first pushing inside and then pushing outside.
By unfolding w.r.t. using we get the clauses where, for , clause is , and we say that clauses are derived from . From we derive the new program .
The following subsumption rule allows us to remove from a clause such that .
R5. Subsumption. Let : be a clause in program and let in be a variant of , for some conjunction of literals and substitution . Then, we say that is subsumed by and by subsumption, from we derive the new program .
The folding rule consists in replacing instances of the bodies of the clauses that define an atom by the corresponding instance of . Similarly to the case of the unfolding rule, we have two folding rules: (1) positive folding and (2) negative folding. They correspond, respectively, to the case where folding is applied to positive or negative occurrences of literals.
R6. Positive Folding. Let be a clause in and let be a variant of without variables in common with . Let the definition of a predicate in Defs consist of the clause , where is a non-empty conjunction of literals. Suppose that there exists a substitution such that clause is of the form and, for every variable varsvars, the following conditions hold: (i) is a variable not occurring in , and (ii) does not occur in the term , for any variable occurring in and different from .
By folding using we get the clause : , and we say that clause is derived from . From we derive the new program .
R7. Negative Folding. Let be a clause in and let Defs be a variant of Defswithout variables in common with . Let the definition of a predicate in Defs consist of the clauses , with , such that, for , is a literal and has no existential variables. Suppose that there exists a substitution such that clause is of the form , where, for , if is the negative literal then is , and if is the positive literal then is .
By folding using we get the clause : , and we say that clause is derived from . From we derive the program .
Note that the negative folding rule is not included in the sets of transformation rules presented in [Roychoudhury et al. (2002), Seki (1991), Seki (2010)]. The negative folding rule presented in [Fioravanti et al. (2004), Pettorossi and Proietti (2000)] corresponds to our rule R7 in the case where .
4 Correctness of the Transformation Rules
Now let us introduce the notion of correctness of a transformation sequence w.r.t. the perfect model semantics.
Definition 1 (Correctness of a Transformation Sequence)
Let be a locally stratified -program and , with , be a transformation sequence. We say that is correct if (i) Defs and are locally stratified -programs and (ii) Defs.
In order to guarantee the correctness of a transformation sequence (see Theorem 4 below) we will require that the application of the transformation rules satisfy some suitable conditions that refer to a given local stratification . In order to state those conditions we need the following definitions.
Definition 2 (-Maximal Atom)
Consider a clause : . An atom in is said to be -maximal if, for every valuation and for every literal in , we have .
Definition 3 (-Tight Clause)
A clause : is said to be -tight if there exists a -maximal atom in such that, for every valuation , .
Definition 4 (Descendant Clause)
A clause is said to be a descendant of a clause if either is itself or there exists a clause such that is derived from by using a rule in , and is a descendant of .
Definition 5 (Admissible Transformation Sequence)
Let be a locally stratified -program and let be a local stratification for . A transformation sequence , with , is said to be admissible if:
(1) every clause in Defs is locally stratified w.r.t. ,
(2) for , if is derived from by positive folding of clause using clause , then: (2.1) is -tight and either (2.2.i) the head predicate of occurs in , or (2.2.ii) is a descendant of a clause in , with , such that has been derived by positive unfolding of a clause in w.r.t. an atom which is -maximal in the body of and whose predicate occurs in , and
(3) for , if is derived from by applying the negative folding rule thereby deriving a clause , then is locally stratified w.r.t. .
Note that Condition (1) can always be fulfilled because the predicate introduced in program by rule R1 does not occur in any of the programs . Conditions (2) and (3) cannot be checked in an algorithmic way for arbitrary programs and local stratification functions. In particular, the program property of being locally stratified is undecidable. However, there are significant classes of programs, such as the stratified programs, where these conditions are decidable and easy to verify.
The following Lemma 4 and Theorem 4, whose proofs can be found in the Appendix, show that: (i) when constructing an admissible transformation sequence , the application of the transformation rules preserves the local stratification for the initial program and, thus, all programs in the transformation sequence are locally stratified w.r.t. , and (ii) any admissible transformation sequence preserves the perfect model of the initial program.
[Preservation of Local Stratification] Let be a locally stratified -program, be a local stratification for , and be an admissible transformation sequence. Then the programs Defs, are all locally stratified w.r.t. .
[Correctness of Admissible Transformation Sequences] Every admissible transformation sequence is correct.
Now let us make a few comments on Condition (2) of Definition 5 and related conditions presented in the literature. Transformation sequences of stratified programs over finite terms constructed by using rules R1, R3, and R6 have been first considered in [Seki (1991)]. In that paper there is a sufficient condition, called (F4), for the preservation of the perfect model. Condition (F4) is like our Condition (2) except that (F4) does not require the -maximality of the atom w.r.t. which positive unfolding is performed. A set of transformation rules which includes also the negative unfolding rule R4, was proposed in [Pettorossi and Proietti (2000)] for locally stratified logic programs, and in [Fioravanti et al. (2004)] for locally stratified constraint logic programs. In [Seki (2010)] Condition (F4) is shown to be insufficient for the preservation of the perfect model if rule R4 is used together with rules R1, R3, and R6, as demonstrated by the following example.
Let us consider the initial program . By rule R1 we introduce the clause : and we derive program and . By rule R3 we unfold w.r.t. and we get the clause : . We derive program . Thus, Condition (F4) is satisfied. By rule R4 we unfold w.r.t. and we get : . We derive program . By rule R6 we fold clause using clause , and we get : . We derive program and . We have that and . Thus, the transformation sequence is not correct.
In order to guarantee the preservation of the perfect model semantics, [Seki (2010)] has proposed the following stronger applicability condition for negative unfolding:
Condition (NU): the negative unfolding rule R4 can be applied only if it does not increase the number of positive occurrences of atoms in the body of any derived clause.
Indeed, in the incorrect transformation sequence of Example 2 the negative unfolding does not comply with this Condition (NU). However, Condition (NU) is very restrictive, because it forbids the unfolding of a clause w.r.t. a negative literal when the body of a clause defining contains an occurrence of a negative literal. Unfortunately, many of the correct transformation strategies proposed in [Pettorossi and Proietti (2000), Fioravanti et al. (2004)] would be ruled out if Condition (NU) is enforced. Our Condition (2) is more liberal than Condition (NU) and, in particular, it allows us to unfold w.r.t. a negative literal also if the body of a clause defining contains occurrences of negative literals. The following is an example of a correct, admissible transformation sequence which violates Condition (NU).
Let us consider the initial program , , and the transformation sequence we now construct starting from . By rule R1 we introduce the following clause
and we derive . By taking a local stratification function such that, for all ground terms and , , we have that is -tight and is a -maximal atom in its body. By unfolding w.r.t. we derive , where
By unfolding, clause is removed and we derive . By unfolding w.r.t. we derive , where
By unfolding w.r.t. , we derive , where
By applying rule R6, we fold clause using clause and derive the final program , where
The transformation sequence is admissible and, thus, correct. In particular, the application of rule R6 satisfies Condition (2) of Definition 5 because is -tight and is a descendant of which has been derived by unfolding w.r.t. a -maximal atom whose predicate occurs in .
Note that, violates Condition (NU) because, by unfolding clause w.r.t. , the number of positive occurrences of atoms in the body of the derived clause is larger than that number in .
Finally, note that the incorrect transformation sequence of Example 2 is not an admissible transformation sequence in the sense of our Definition 5, because it does not comply with Condition (2). Indeed, consider any local stratification . The atom is not -maximal in because depends on and, hence, . Thus, the positive folding rule R6 is applied to the clause which is not a descendant of any clause derived by unfolding w.r.t. a -maximal atom.
5 Verifying Properties of -Programs by Program Transformation
In this section we will outline a general method, based on the transformation rules presented in Section 3, for verifying properties of -programs. Then we will see our transformation-based verification method in action in the proof of: (i) the non-emptiness of the language accepted by a Büchi automaton, and (ii) containment between -regular languages.
We assume that we are given an -program defining a unary predicate prop of type ilist, which specifies a property of interest, and we want to check whether or not . Our verification method consists of two steps.
Step 2. We apply to the decision procedure of [Pettorossi et al. (2010)] for monadic -programs and we check whether or not .
Our verification method is an extension to -programs of the transformation-based method for proving properties of logic programs on finite terms presented in [Pettorossi and Proietti (2000)]. Furthermore, our method is more powerful than the transformation-based method for verifying CTL properties of finite state reactive systems presented in [Pettorossi et al. (2010)]. Indeed, at Step 1 of the verification method proposed here, (i) we start from an arbitrary -program, instead of an -program which encodes the branching time temporal logic CTL, and (ii) we use transformation rules more powerful than those in [Pettorossi et al. (2010)]. In particular, similarly to [Pettorossi and Proietti (2000)], the rules applied at Step 1 allow us to eliminate the existential variables from program , while the transformation presented in [Pettorossi et al. (2010)] consists of a specialization of the initial program w.r.t. the property to be verified.
Note that there exists no algorithm which always succeeds in transforming an -program into a monadic -program. Indeed, (i) the problem of verifying whether or not, for any -program and unary predicate prop, is undecidable, because the class of -programs includes the locally stratified logic programs on finite terms, and (ii) the proof method for monadic -programs presented in [Pettorossi et al. (2010)] is complete. However, we believe that automatic transformation strategies can be proposed for significant subclasses of -programs along the lines of [Proietti and Pettorossi (1995), Pettorossi and Proietti (2000)].
Definition 6 (Monadic -Programs)
A monadic -clause is an -clause of the form , with , such that: (i) is an atom of the form or , where is a predicate of type ilist and , (ii) for is either an atom or a negated atom , where is of the form or , and is a predicate of type ilist, and (iii) there exists a level mapping such that, for if is an atom and , then else . A monadic -program is a finite set of monadic -clauses.
Example 4 (Non-Emptiness of Languages Accepted by Büchi Automata)
In this first application of our verification method, we will consider Büchi automata, which are finite automata acting on infinite words [Thomas (1990)], and we will check whether or not the language accepted by a Büchi automaton is empty. It is well known that this verification problem has important applications in the area of model checking (see, for instance, [Clarke et al. (1999)]).
A Büchi automaton is a nondeterministic finite automaton , where, as usual, is the input alphabet, is the set of states, is the initial state, is the transition relation, and is the set of final states. A run of the automaton on an infinite input word is an infinite sequence of states such that is the initial state and, for all , . Let denote the set of states that occur infinitely often in the infinite sequence of states. An infinite word is accepted by if there exists a run of on such that or, equivalently, if there is no state in such that every state , with , is not final. The language accepted by is the subset of , denoted , of the infinite words accepted by . In order to check whether or not the language is empty, we construct an -program which defines a unary predicate accepting_run such that:
The predicate accepting_run is defined by the following formulas:
where, for all , for all , for all , for all , (i) iff , (ii) iff , (iii) iff , (iv) iff , (v) iff , and (vi) iff .
By and (1)–(3) above, iff there exists an infinite sequence of states such that: (i) is the initial state , (ii) for all , there exists such that (see (2)), and (iii) there exists no state , with , in such that, for all , (see (3)).
Now we introduce an -program defining the predicates accepting_run, run, rejecting, nat, occ, and geq. In particular, clause 1 corresponds to formula (1), clauses 2–4 correspond to formula (2), and clauses 5 and 6 correspond to formula (3). (Actually, clauses 1–6 can be derived from formulas (1)–(3) by applying the Lloyd-Topor transformation [Lloyd (1987)].) In program any infinite sequence of states is represented by the infinite list of constants.
Given a Büchi automaton , the encoding -program consists of the following clauses (independent of ):
together with the clauses (depending on ) which define the predicates initial, tr, and final, where: for all states , for all symbols , (i) holds iff is , (ii) holds iff , and (iii) holds iff .
The -program is locally stratified w.r.t. the stratification function defined as follows: for every atom in , , except that: for every element in , for every infinite list in , (i) , and (ii) accepting_run.
Now, let us consider a Büchi automaton such that:
, , , ,
which can be represented by the following graph:
For this automaton , program consists of clauses 1–12 and the following clauses 13–18 that encode the initial state (clause 13), the transition relation (clauses 14–17), and the final state (clause 18):
13. 14. 15.
16. 17. 18.
In order to check whether or not we proceed in two steps as indicated at the beginning of this Section 5. In the first step we use the rules of Section 3 for transforming the -program into a monadic -program . This transformation aims at the elimination of the existential variables from clauses 1–6, with the objective of deriving unary predicates of type ilist. We start from clause 6 and, by instantiation of the variable of type ilist, we get:
By some unfolding and subsumption steps, from clauses 19 and 20 we get:
Note that clauses 21–24 are descendants of clauses derived by unfolding clauses 19 and 20 w.r.t. the -maximal atom . By rule R1, we introduce:
This clause is -tight by taking, for every infinite list of states, . By folding clause 21 using clause 25, and folding clauses 22 and 24 using clause 6 (indeed, without loss of generality, we may assume that clauses 1–6 have been introduced by rule R1), we get:
By instantiation of the variable and by some unfolding and subsumption steps, from clause 25 we get:
Note that clause 29 is a descendant of clause 25, that has been unfolded w.r.t. the -maximal atom . By folding clause 29 using clause 25 we get:
At this point we have obtained the definitions of the predicates exists_final and (that is, clauses 23, 26–28, 30, and 31) that do not have existential variables.
Now the transformation of program proceeds by performing on clauses 1–5 a sequence of transformation steps, which is similar to the one we have performed above on clause 6 for eliminating its existential variables. By doing so, we get:
The final -program obtained from program , consists of clauses 30–40 and it is a monadic -program.
Now, in the second step of our verification method, we check whether or not holds in by applying the proof method of [Pettorossi et al. (2010)]. We construct the tree depicted in Figure 1, where the literals occurring in the two lowest levels are the same (see the two rectangles) and, thus, we have detected an infinite loop. According to the conditions given in Definition 6 of [Pettorossi et al. (2010)], this tree is a proof of . The run is a witness for and corresponds to the accepted word . Thus, .