<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>Verification of Imperative Programs by Transforming Constraint Logic Programs?</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Emanuele De Angelis</string-name>
          <email>emanuele.deangelis@unich.it</email>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Fabio Fioravanti</string-name>
          <email>fioravanti@unich.it</email>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Alberto Pettorossi</string-name>
          <email>pettorossi@disp.uniroma2.it</email>
          <xref ref-type="aff" rid="aff1">1</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Maurizio Proietti</string-name>
          <email>maurizio.proietti@iasi.cnr.it</email>
          <xref ref-type="aff" rid="aff2">2</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>DEC, University 'G. D'Annunzio'</institution>
          ,
          <addr-line>Pescara</addr-line>
          ,
          <country country="IT">Italy</country>
        </aff>
        <aff id="aff1">
          <label>1</label>
          <institution>DICII, University of Rome Tor Vergata</institution>
          ,
          <addr-line>Rome</addr-line>
          ,
          <country country="IT">Italy</country>
        </aff>
        <aff id="aff2">
          <label>2</label>
          <institution>IASI-CNR</institution>
          ,
          <addr-line>Rome</addr-line>
          ,
          <country country="IT">Italy</country>
        </aff>
      </contrib-group>
      <fpage>83</fpage>
      <lpage>98</lpage>
      <abstract>
        <p>We present a method for verifying partial correctness properties of imperative programs that manipulate integers and arrays by using techniques based on the transformation of constraint logic programs (CLP). We use CLP as a metalanguage for representing imperative programs, their executions, and their properties. First, we encode the correctness of an imperative program, say prog, as the negation of a predicate incorrect defined by a CLP program T . By construction, incorrect holds in the least model of T if and only if the execution of prog from an initial configuration eventually halts in an error configuration. Then, we apply to program T a sequence of transformations that preserve its least model semantics. These transformations are based on well-known transformation rules, such as unfolding and folding, guided by suitable transformation strategies, such as specialization and generalization. The objective of the transformations is to derive a new CLP program TransfT where the predicate incorrect is defined either by (i) the fact 'incorrect.' (and in this case prog is not correct), or by (ii) the empty set of clauses (and in this case prog is correct). In the case where we derive a CLP program such that neither (i) nor (ii) holds, we iterate the transformation. Since the problem is undecidable, this process may not terminate. We show through examples that our method can be applied in a rather systematic way, and is amenable to automation by transferring to the field of program verification many techniques developed in the field of program transformation.</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>-</title>
      <p>
        In the last decade formal techniques have received a renewed attention as the
basis of a methodology for increasing the reliability of software artifacts and
reducing the cost of software production. In particular, great efforts have been
made to devise automatic techniques such as software model checking [
        <xref ref-type="bibr" rid="ref23">23</xref>
        ], for
verifying the correctness of programs with respect to their specifications.
? A preliminary version of this paper appears in [
        <xref ref-type="bibr" rid="ref10">10</xref>
        ].
In many software model checking techniques, the use of constraints has been
very effective both for constructing models of programs and for reasoning about
them [
        <xref ref-type="bibr" rid="ref12 ref18 ref2 ref20 ref22 ref33 ref34 ref8 ref9">2, 8, 9, 12, 18, 20, 22, 33, 34</xref>
        ]. Several kinds of constraints have been
considered, such as equalities and inequalities over booleans, integers, reals, and finite
or infinite trees. By using constraints we can represent in a symbolic, compact
way the (possibly infinite) sets of values computed by programs and, in general,
the sets of states which are reached during program executions. Then, by
using powerful solvers specifically designed for the classes of constraints we have
mentioned above, we can reason about program properties in an efficient way.
      </p>
      <p>
        In this paper we consider a simple imperative programming language with
integer and array variables and we use Constraint Logic Programming (CLP) [
        <xref ref-type="bibr" rid="ref21">21</xref>
        ]
as a metalanguage for representing imperative programs, their executions, and
the properties to be verified. We use constraints consisting of linear equalities
and inequalities over integers. Note, however, that the method presented here is
parametric with respect to the constraint domain which is used. By following an
approach originally presented in [
        <xref ref-type="bibr" rid="ref33">33</xref>
        ], a given imperative program prog and its
interpreter are first encoded as a CLP program. Then, the proofs of the properties
of interest about the program prog are sought by analyzing that derived CLP
program. In order to improve the efficiency of that analysis, it is advisable to first
compile-away the CLP interpreter of the language in which prog is written. This
is done by specializing the interpreter with respect to the given program prog
using well-known program specialization techniques [
        <xref ref-type="bibr" rid="ref24 ref33">24, 33</xref>
        ].
      </p>
      <p>
        In previous papers [
        <xref ref-type="bibr" rid="ref16 ref9">9, 16</xref>
        ] we have shown that program specialization can
be used not only as a preprocessing step to improve the efficiency of program
analysis, but also as a means of analysis on its own. In this paper, we extend
that approach and we propose a verification method based on more general
unfold/fold transformation rules for CLP programs [
        <xref ref-type="bibr" rid="ref13 ref37 ref5">5, 13, 37</xref>
        ].
      </p>
      <p>
        Transformation-based verification techniques are very appealing because they
are parametric with respect to both the programming languages in which
programs are written, and the logics in which the properties of interest are specified.
Moreover, since the output of a transformation-based verification method is a
program which is equivalent to the given program with respect to the
properties of interest, we can apply a sequence of transformations, thereby refining the
analysis to the desired degree of precision (see, for instance, [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ]).
      </p>
      <p>The specific contributions of this paper are the following. We present a
verification method based on a set of transformation rules which includes the rules
for performing conjunctive definition , conjunctive folding, and goal replacement,
besides the usual rules for unfolding and constraint manipulation which are used
during program specialization. The rules for conjunctive definition and
conjunctive folding allow us to introduce and transform new predicates defined in terms
of conjunctions of old predicates, while program specialization can only deal with
new predicates that correspond to specialized versions of exactly one old
predicate. The goal replacement rule allows us to replace conjunctions of predicates
and constraints by applying equivalences that hold in the least model of the CLP
program at hand, while program specialization can only replace conjunctions of
constraints.</p>
      <p>
        By using these more powerful definition and folding rules, we extend the
specialization-based verification method in the following two directions: (i) we
verify programs with respect to specifications given by sets of CLP clauses (for
instance, recursively defined relations among program variables), whereas
program specialization can only deal with specifications given by constraints, and
(ii) we verify programs manipulating arrays and other data structures by
applying equivalences between predicates that axiomatize suitable properties of those
data structures (for instance, the ones deriving from the axiomatization of the
theory of arrays [
        <xref ref-type="bibr" rid="ref31">31</xref>
        ]).
      </p>
      <p>The paper is organized as follows. In Section 2 we present our
transformationbased verification method. First, we introduce a simple imperative language and
we describe how correctness properties of imperative programs can be translated
into predicates defined by CLP programs. We also present a general strategy
for applying the transformation rules to CLP programs, with the objective of
verifying the properties of interest. Next, we present two examples of application
of our verification method. In particular, in Section 3 we show how we deal with
specifications given by recursive CLP clauses, and in Section 4 we show how we
deal with programs which manipulate arrays. Finally, in Section 5 we discuss
the related work which has been recently done in the area of automatic program
verification.
2</p>
    </sec>
    <sec id="sec-2">
      <title>The Transformation-Based Verification Method</title>
      <p>We consider an imperative C-like programming language with integer and array
variables, assignments (=), sequential compositions (;), conditionals (if and
if else), while-loops (while), and jumps (goto). A program is a sequence of
(labeled) commands, and in each program there is a unique halt command
which, when executed, causes program termination.</p>
      <p>
        The semantics of our language is defined by a transition relation, denoted
=⇒, between configurations . Each configuration is a pair hhc, δii of a command c
and an environment δ. An environment δ is a function that maps: (i) every integer
variable identifier x to its value v, and (ii) every integer array identifier a to a
finite function from the set {0, . . . , dim(a)−1}, where dim(a) is the dimension of
the array a, to the set of the integer numbers. The definition of the relation =⇒
is similar to the ‘small step’ operational semantics given in [
        <xref ref-type="bibr" rid="ref35">35</xref>
        ], and is omitted.
      </p>
      <p>Given an imperative program prog , we address the problem of verifying
whether or not, starting from any initial configuration that satisfies the
property ϕinit , the execution of prog eventually leads to a final configuration that
satisfies the property ϕerror , also called an error configuration . This problem is
formalized by defining an incorrectness triple of the form {{ϕinit }} prog {{ϕerror }},
where ϕinit and ϕerror are encoded by CLP predicates defined by (possibly
recursive) clauses. We say that a program prog is incorrect with respect to ϕinit
and ϕerror , whose free variables are assumed to be among z1, . . . , zr, if there
exist environments δinit and δh such that: (i) ϕinit (δinit (z1), . . . , δinit (zr)) holds,
(ii) hh`0 : c0, δinit ii =⇒∗ hh`h : halt, δh ii, and (iii) ϕerror (δh (z1), . . . , δh (zr)) holds,
where `0 : c0 is the first labeled command of prog and `h : halt is the unique
halt command of prog. A program is said to be correct with respect to ϕinit and
ϕerror iff it is not incorrect with respect to ϕinit and ϕerror . Note that this notion
of correctness is equivalent to the usual notion of partial correctness specified by
the Hoare triple {ϕinit } prog {¬ϕerror }.</p>
      <p>Our verification method is based on the formalization of the notion of
program incorrectness by using a predicate incorrect defined by a CLP program.</p>
      <p>
        In this paper a CLP program is a finite set of clauses of the form A :- c,B,
where A is an atom, c is a constraint (that is, a possibly empty conjunction
of linear equalities and inequalities over the integers), and B is a goal (that
is, a possibly empty conjunction of atoms). The conjunction c,B is called a
constrained goal. A clause of the form: A :- c is called a constrained fact. We refer
to [
        <xref ref-type="bibr" rid="ref21">21</xref>
        ] for other notions of CLP with which the reader might be not familiar.
      </p>
      <p>We translate the problem of checking whether or not the program prog is
incorrect with respect to the properties ϕinit and ϕerror into the problem of
checking whether or not the predicate incorrect is a consequence of the CLP
program T defined by the following clauses:
incorrect :- initConf(X), reach(X).
reach(X) :- tr(X, X1), reach(X1).</p>
      <p>reach(X) :- errorConf(X).
together with the clauses for the predicates initConf(X), errorConf(X), and
tr(X, X1). They are defined as follows: (i) initConf(X) encodes an initial
configuration satisfying the property ϕinit , (ii) errorConf(X) encodes an error
configuration satisfying the property ϕerror , and (iii) tr(X, X1) encodes the transition
relation =⇒. (Note that in order to define initConf(X), errorConf(X), and
tr(X, X1) and, in particular, to represent operations over the integer variables
and the elements of arrays, we need constraints.) The predicate reach(X) holds
if an error configuration Y such that errorConf(Y) holds, can be reached from
the configuration X.</p>
      <p>
        The imperative program prog is correct with respect to the properties ϕinit
and ϕerror iff incorrect 6∈ M (T ), where M (T ) denotes the least model of
program T [
        <xref ref-type="bibr" rid="ref21">21</xref>
        ]. Due to the presence of integer variables and array variables, M (T )
is in general an infinite model, and both the bottom-up and top-down evaluation
of the query incorrect may not terminate. In order to deal with this difficulty,
we propose an approach to program verification which is symbolic and, by using
program transformations, allows us to avoid the exhaustive exploration of the
possibly infinite space of reachable configurations.
      </p>
      <p>
        Our verification method consists in applying to program T a sequence of
program transformations that preserve the least model M (T ) [
        <xref ref-type="bibr" rid="ref13 ref15">13, 15</xref>
        ]. In particular,
we apply the following transformation rules, collectively called unfold/fold rules:
(i) (conjunctive) definition , (ii) unfolding, (iii) goal replacement, (iv) clause
removal, and (v) (conjunctive) folding. Our verification method is made out of the
following two steps.
Step (A): Removal of the Interpreter. Program T is specialized with respect to the
given prog (on which tr depends), initConf, and errorConf, thereby deriving a
new program T 1 such that: (i) incorrect ∈ M (T ) iff incorrect ∈ M (T 1), and
(ii) tr does not occur explicitly in T 1 (in this sense we say that the interpreter
is removed or compiled-away).
      </p>
      <p>Step (B): Propagation of the Initial and Error Properties. By applying a sequence
of unfold/fold transformation rules, the CLP program T 1 is transformed into a
new CLP program T 2 such that the program prog is correct with respect to the
given initial and error properties iff incorrect 6∈ M (T 2).</p>
      <p>
        The objective of Step (B) is to propagate the initial and the error properties
so as to derive a program T 2 where the predicate incorrect is defined by either
(i) the fact ‘incorrect.’ (in which case prog is incorrect), or (ii) the empty set
of clauses (in which case prog is correct). In the case where neither (i) nor (ii)
holds, that is, in program T 2 the predicate incorrect is defined by a non-empty
set of clauses not containing the fact ‘incorrect.’, we cannot conclude anything
about the correctness of prog and, similarly to what has been proposed in [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ],
we iterate Step (B) in the hope of deriving a program where either (i) or (ii)
holds. Obviously, due to undecidability limitations, it may be the case that we
never get a program where either (i) or (ii) holds.
      </p>
      <p>
        Steps (A) and (B) are both instances of the Transform strategy outlined in
Figure 1 below. These two instances are obtained by using two different ways
of controlling the application of the transformation rules. In particular, in the
instance of the Transform strategy that realizes Step (A) we never apply the goal
replacement rule and the resulting strategy coincides with the fully automatic
specialization strategy presented in [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ].
      </p>
      <p>In the Transform strategy we make use of the following rules, where P is
the input CLP program, and Defs is a set of clauses, called definition clauses ,
constructed as we indicate in that strategy.</p>
      <p>Definition Rule. By this rule we introduce a clause of the form newp(X) :- c,G,
where newp is a new predicate symbol, X is a tuple of variables occurring in (c,G),
c is a constraint, and G is a non-empty conjunction of atoms.</p>
      <p>Unfolding Rule. Given a clause C of the form H :- c,L,A,R, where H and A are
atoms, c is a constraint, and L and R are (possibly empty) conjunctions of atoms,
let us consider the set {Ki :- ci,Bi | i = 1, . . . , m} made out of the (renamed
apart) clauses of P such that, for i = 1, . . . , m, A is unifiable with Ki via the most
general unifier ϑi and (c,ci) ϑi is satisfiable (thus, the unfolding rule performs
some constraint solving operations). By unfolding C w.r.t. A using P , we derive
the set {(H :- c,ci,L,Bi,R) ϑi | i = 1, . . . , m} of clauses.</p>
      <p>Goal Replacement Rule. If a constrained goal c1, G1 occurs in the body of a clause
C, and M (P ) |= ∀ (c1, G1 ↔ c2, G2), then we derive a new clause D by replacing
c1, G1 by c2, G2 in the body of C.</p>
      <p>The equivalences which are needed for goal replacements are called laws
and their validity in M (P ) can be proved once and for all, before applying the
Transform strategy.
Input : Program P .</p>
      <p>Output : Program TransfP such that incorrect ∈ M (P ) iff incorrect ∈ M (TransfP).
Initialization:
Let InDefs be the set of all clauses of P whose head is the atom incorrect;
TransfP := ∅ ; Defs := InDefs ;
while in InDefs there is a clause C do</p>
      <p>Unfolding: Apply the unfolding rule at least once using P , and derive from C
a set U(C) of clauses;
Goal Replacement: Apply a sequence of goal replacements, and derive from</p>
      <p>U(C) a set R(C) of clauses;
Clause Removal: Remove from R(C) all clauses whose body contains an
unsatisfiable constraint;
Definition &amp; Folding: Introduce a (possibly empty) set NewDefs of new
predicate definitions and add them to Defs and to InDefs;
Fold the clauses in R(C) different from constrained facts by using the clauses
in Defs, and derive a set F(C) of clauses;</p>
      <p>InDefs := InDefs − {C};
end-while;</p>
      <p>TransfP := TransfP ∪ F(C);
Removal of Useless Clauses:
Remove from TransfP all clauses whose head predicate is useless.</p>
      <p>Folding Rule. Given a clause E of the form: H :- e, L, Q, R and a clause D in
Defs of the form K :- d, D such that: (i) for some substitution ϑ, Q = D ϑ, and (ii)
∀ (e → d ϑ) holds, then by folding E using D we derive H :- e, L, K ϑ, R.
Removal of Useless Clauses. The set of useless predicates in a given program Q
is the greatest set U of predicates occurring in Q such that p is in U iff every
clause with head predicate p is of the form p(X) :- c, G1, q(Y), G2, for some q in
U . A clause in a program Q is useless if the predicate of its head is useless in Q.</p>
      <p>
        The termination of the Transform strategy is guaranteed by suitable
techniques for controlling the unfolding and the introduction of new predicates. We
refer to [
        <xref ref-type="bibr" rid="ref28">28</xref>
        ] for a survey of techniques which ensure the finiteness of unfolding.
The introduction of new predicates is controlled by applying generalization
operators based on various notions, such as widening, convex hull, most specific
generalization, and well-quasi ordering, which have been proposed for analyzing
and transforming CLP programs (see, for instance, [
        <xref ref-type="bibr" rid="ref11 ref17 ref32 ref8">8, 11, 17, 32</xref>
        ]).
      </p>
      <p>
        The correctness of the strategy with respect to the least model semantics
directly follows from the fact that the application of the transformation rules
complies with some suitable conditions that guarantee the preservation of that
model [
        <xref ref-type="bibr" rid="ref13">13</xref>
        ].
      </p>
      <p>Theorem 1. (Termination and Correctness of the Transform strategy) (i) The
Transform strategy terminates. (ii) Let program TransfP be the output of the
Transform strategy applied on the input program P . Then, incorrect ∈ M (P )
iff incorrect ∈ M (TransfP).
3</p>
    </sec>
    <sec id="sec-3">
      <title>Verification of Recursively Defined Properties</title>
      <p>
        In this section we will show, through an example, that our verification method
can be used when the initial properties and the error properties are specified
by (possibly recursive) CLP clauses, rather than by constraints only (as done,
for instance, in [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ]). In order to deal with that kind of properties, during the
Definition &amp; Folding phase of the Transform strategy, we allow ourselves to
introduce new predicates which are defined by clauses of the form: Newp :- c, G,
where Newp is an atom with a new predicate symbol, c is a constraint, and G is a
conjunction of one or more atoms. This kind of predicate definitions allows us to
perform program verifications that cannot be done by the technique presented
in [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ], where the goal G is assumed to be a single atom.
      </p>
      <p>Let us consider the following program GCD that computes the greatest
common divisor z of two positive integers m and n, denoted gcd (m, n, z).</p>
      <p>GCD : `0: x = m ;
`1: y = n ;
`2: while (x 6= y) { if (x &gt; y) x = x−y ; else y = y−x ; } ;
`3: z = x ;
`h: halt
We also consider the incorrectness triple {{ϕinit (m, n)}} GCD {{ϕerror (m, n, z)}},
where:
(i) ϕinit (m, n) is m ≥ 1 ∧ n ≥ 1, and (ii) ϕerror (m, n, z) is ∃ d (gcd (m, n, d) ∧ d 6= z).
These properties ϕinit and ϕerror are defined by the following CLP clauses 1 and
2–5, respectively:
1. phiInit(M, N) :- M ≥ 1, N ≥ 1.
2. phiError(M, N, Z) :- gcd(M, N, D), D 6= Z.
3. gcd(X, Y, D) :- X &gt; Y, X1 = X−Y, gcd(X1, Y, D).
4. gcd(X, Y, D) :- X &lt; Y, Y1 = Y−X, gcd(X, Y1, D).
5. gcd(X, Y, D) :- X = Y, Y = D.</p>
      <p>The predicates initConf and errorConf specifying the initial and the error
configurations, respectively, are defined by the following clauses:</p>
      <sec id="sec-3-1">
        <title>6. initConf(cf(cmd(0, asgn(int(x), int(m))),</title>
        <p>[[int(m), M], [int(n), N], [int(x), X], [int(y), Y], [int(z), Z]]))</p>
        <p>:- phiInit(M, N).
7. errorConf(cf(cmd(h, halt),
[[int(m), M], [int(n), N], [int(x), X], [int(y), Y], [int(z), Z]]))
:</p>
        <p>phiError(M, N, Z).</p>
        <p>Thus, the CLP program encoding the given incorrectness triple consists of clauses
1–7 above, together with the clauses defining the predicates incorrect, reach,
and tr given as indicated in Section 2.
Now we perform Step (A) of our verification method, which consists in the
removal of the interpreter, and we derive the following CLP program:
8. incorrect :- M ≥ 1, N ≥ 1, X = M, Y = N, new1(M, N, X, Y, Z).</p>
        <p>9. new1(M, N, X, Y, Z) :- X &gt; Y, X1 = X−Y, new1(M, N, X1, Y, Z).
10. new1(M, N, X, Y, Z) :- X &lt; Y, Y1 = Y−X, new1(M, N, X, Y1, Z).
11. new1(M, N, X, Y, Z) :- X = Y, Z = X, Z 6= D, gcd(M, N, D).</p>
        <p>By moving the constrained atom ‘Z 6= D, gcd(M, N, D)’ from the body of clause 11
to the body of clause 8, we can rewrite clauses 8 and 11 as follows (this rewriting
is correct because in clauses 9 and 10 the predicate new1 modifies neither the
value of M nor the value of N):
8r. incorrect :- M ≥ 1, N ≥ 1, X = M, Y = N, Z 6= D, gcd(M, N, D), new1(M, N, X, Y, Z).
11r. new1(M, N, X, Y, Z) :- X = Y, Z = X.</p>
        <p>Note that we could avoid performing the above rewriting and obtain a similar
program where the constraints characterizing the initial and the error properties
occur in the same clause by starting our derivation from a more general definition
of the reachability relation. However, an in-depth analysis of this variant of our
verification method is beyond the scope of this paper.</p>
        <p>Now we will perform Step (B) of the verification method by applying the
Transform strategy to the derived program consisting of clauses {3, 4, 5, 8r, 9, 10,
11r}. Initially, we have that the sets InDefs and Defs of definition clauses are
both equal to {8r}.</p>
        <p>Unfolding. We start off by unfolding clause 8r w.r.t. the atom new1(M, N, X, Y, Z),
and we get:
12. incorrect :- M ≥ 1, N ≥ 1, X = M, Y = N, X &gt; Y, X1 = X−Y, Z 6= D, gcd(M, N, D),
new1(M, N, X1, Y, Z).
13. incorrect :- M ≥ 1, N ≥ 1, X = M, Y = N, X &lt; Y, Y1 = Y−X, Z 6= D, gcd(M, N, D),
new1(M, N, X, Y1, Z).
14. incorrect :- M ≥ 1, N ≥ 1, X = M, Y = N, X = Y, Z = X, Z 6= D, gcd(M, N, D).
By unfolding clauses 12, 13, and 14 w.r.t. the atom gcd(M, N, D), we derive:
15. incorrect :- M ≥ 1, N ≥ 1, M &gt; N, X1 = M−N, Z 6= D, gcd(X1, N, D),
new1(M, N, X1, N, Z).
16. incorrect :- M ≥ 1, N ≥ 1, M &lt; N, Y1 = N−M, Z 6= D, gcd(M, Y1, D),
new1(M, N, M, Y1, Z).
(The unfolding of clause 14 produces the empty set of clauses because the
constraint ‘X = M, Z = X, Z 6= D, M = D’ is unsatisfiable.) The Goal Replacement and
Clause Removal phases leave the set of clauses produced by the Unfolding
phase unchanged, because no laws are available for the predicate gcd.
Definitions &amp; Folding. In order to fold clauses 15 and 16, we perform a
generalization step and we introduce a new predicate defined by the following clause:
17. new2(M, N, X, Y, Z, D) :- M ≥ 1, N ≥ 1, Z 6= D, gcd(X, Y, D), new1(M, N, X, Y, Z).
The body of this clause 17 is the most specific generalization of the bodies of
clause 8r (which is the only clause in Defs), and clauses 15 and 16 (which are the
clauses to be folded). Now, clauses 15 and 16 can be folded by using clause 17,
thereby deriving:
18. incorrect :- M ≥ 1, N ≥ 1, M &gt; N, X1 = M−N, Z 6= D, new2(M, N, X1, N, Z, D).
19. incorrect :- M ≥ 1, N ≥ 1, M &lt; N, Y1 = N−M, Z 6= D, new2(M, N, M, Y1, Z, D).
Clause 17 defining the new predicate new2 is added to Defs and InDefs and,
since the latter set is not empty, we perform a new iteration of the while-loop
body of the Transform strategy.</p>
        <p>Unfolding. By unfolding clause 17 w.r.t. new1(M,N,X,Y,Z) and then unfolding
the resulting clauses w.r.t. gcd(X,Y,Z), we derive:
20. new2(M, N, X, Y, Z, D) :- M ≥ 1, N ≥ 1, X &gt; Y, X1 = X−Y, Z 6= D, gcd(X1, Y, D),
new1(M, N, X1, Y, Z).
21. new2(M, N, X, Y, Z, D) :- M ≥ 1, N ≥ 1, X &lt; Y, Y1 = Y−X, Z 6= D, gcd(X, Y1, D),
new1(M, N, X, Y1, Z).</p>
        <p>Definition &amp; Folding. Clauses 20 and 21 can be folded by using clause 17,
and we derive:
22. new2(M, N, X, Y, Z, D) :- M ≥ 1, N ≥ 1, X &gt; Y, X1 = X−Y, Z 6= D, new2(M, N, X1, Y, Z).
23. new2(M, N, X, Y, Z, D) :- M ≥ 1, N ≥ 1, X &lt; Y, Y1 = Y−X, Z 6= D, new2(M, N, X, Y1, Z).
No new predicate definition is introduced, and the Transform strategy exits the
while-loop. The final program TransfP is the set {18, 19, 22, 23} of clauses, which
contains no constrained facts. Hence both predicates incorrect and new2 are
useless and all clauses of TransfP can be removed. Thus, the Transform strategy
terminates with TransfP = ∅ and we conclude that the imperative program GCD
is correct w.r.t. the given initial and error properties.
4</p>
      </sec>
    </sec>
    <sec id="sec-4">
      <title>Verification of Array Programs</title>
      <p>In this section we apply our verification method to the following program
ArrayMax which computes the maximal element of an array:</p>
      <p>ArrayMax : `0 : i = 0;
`1 : while (i &lt; n) { if (a[i] &gt; max) max = a[i];</p>
      <p>i = i+1; };
`h : halt
We consider the following incorrectness triple:</p>
      <p>{{ϕinit (i,n,a,max)}} ArrayMax {{ϕerror (n,a,max)}}
where: (i) ϕinit (i,n,a,max) is i ≥ 0 ∧ n = dim(a) ∧ n ≥ i + 1 ∧ max = a[i], and
(ii) ϕerror (n,a,max) is ∃k (0 ≤ k &lt; n ∧ a[k] &gt; max ).</p>
      <p>First, we construct a CLP program T which encodes the above incorrectness
triple, similarly to what has been done in Section 3. In particular, the properties
ϕinit and ϕerror are defined by the following CLP clauses, respectively:
1. phiInit(I, N, A, Max) :- I ≥ 0, N ≥ I+1, read((A, N), I, Max).
2. phiError(N, A, Max) :- K ≥ 0, N &gt; K, Z &gt; Max, read((A, N), K, Z).
The clauses defining the predicates initConf(X) and errorConf(X) which specify
the initial and the error configurations, respectively, are as follows:</p>
      <sec id="sec-4-1">
        <title>3. initConf(cf(cmd(0, asgn(int(i), int(0))),</title>
        <p>[[int(i), I], [int(n), N], [array(a), (A, N)], [int(max), Max]]))
:</p>
        <p>phiInit(I, N, A, Max).
4. errorConf(cf(cmd(h, halt),
[[int(i), I], [int(n), N], [array(a), (A, N)], [int(max), Max]]))
:</p>
        <p>phiError(N, A, Max).</p>
        <p>
          Now we start off by applying Step (A) of our verification method which
consists in the removal of the interpreter. From program T we obtain the following
program T 1:
5. incorrect :- I = 0, N ≥ 1, read((A, N), I, Max), new1(I, N, A, Max).
6. new1(I, N, A, Max) :- I1 = I+1, I &lt; N, I ≥ 0, M &gt; Max, read((A, N), I, M),
new1(I1, N, A, M).
7. new1(I, N, A, Max) :- I1 = I+1, I &lt; N, I ≥ 0, M ≤ Max, read((A, N), I, M),
new1(I1, N, A, Max).
8. new1(I, N, A, Max) :- I ≥ N, K ≥ 0, N &gt; K, Z &gt; Max, read((A, N), K, Z).
As indicated in [
          <xref ref-type="bibr" rid="ref9">9</xref>
          ], in order to propagate the error property, we ‘reverse’ the
derived program T 1 and we get the following program T 1rev:
rev1. incorrect :- b(U), r2(U).
rev2. r2(V) :- trans(U, V), r2(U).
rev3. r2(U) :- a(U).
where the predicates a, b, and trans are defined as follows:
This reversal transformation, which from program T 1 derives program T 1rev ,
can easily be automatedand it is correct in the sense that incorrect ∈ M (T 1)
iff incorrect ∈ M (T 1rev). This equivalence holds because: (i) in program T 1 the
predicate incorrect is defined in terms of the predicate new1 that encodes the
reachability relation from an error configuration to an initial configuration, and
(ii) in program T 1rev the predicate incorrect is defined in terms of the
predicate r2 that also encodes the reachability relation, but this time the encoding
is, so to speak, ‘in the reversed direction’, that is, from an initial configuration
to an error configuration.
        </p>
        <p>Now let us apply Step (B) of our verification method starting from the
program T 1rev.</p>
        <p>Unfolding. First we unfold clause rev1 w.r.t. the atom b(U), and we get:
9. incorrect :- I ≥ N, K ≥ 0, K &lt; N, Z &gt; Max, read((A, N), K, Z),</p>
        <p>r2([new1, I, N, A, Max]).</p>
        <p>Neither Goal Replacement nor Clause Removal is applied.
Definition &amp; Folding. In order to fold clause 9 we introduce the following
clause:
10. new2(I, N, A, Max, K, Z) :- I ≥ N, K ≥ 0, K &lt; N, Z &gt; Max, read((A,N), K, Z),
r2([new1, I, N, A, Max]).</p>
        <p>By folding clause 9 using clause 10, we get:
Now we proceed by performing a second iteration of the body of the while-loop of
the Transform strategy because InDefs is not empty (indeed, clause 10 belongs
to InDefs).</p>
        <p>Unfolding. After some unfoldings from clause 10 we get the following clauses:
12. new2(I1, N, A, M, K, Z) :- I1 = I+1, N = I1, K ≥ 0, K &lt; I1, M &gt; Max, Z &gt; M,
read((A, N), K, Z), read((A, N), I, M), r2([new1, I, N, A, Max]).</p>
        <p>Goal Replacement. We use the following law which is a consequence of the
fact that arrays are finite functions:
Thus, (i) we replace the conjunction of atoms ‘read((A, N), K, Z), read((A, N), I, M)’
occurring in the body of clause 12 by the right hand side of law (L1), and then
(ii) we split the derived clause with disjunctive body into the following two
clauses, each of which corresponds to a disjunct of the right hand side of (L1).
We get the following clauses:
12.1 new2(I1, N, A, M, K, Z) :- I1 = I+1, N = I1, K ≥ 0, K &lt; I1, M &gt; Max, Z &gt; M,</p>
        <p>K = I, M = Z, read((A, N), K, Z), r2([new1, I, N, A, Max]).
12.2 new2(I1, N, A, M, K, Z) :- I1 = I+1, N = I1, K ≥ 0, K &lt; I1, M &gt; Max, Z &gt; M,</p>
        <p>K 6= I, read((A, N), K, Z), read((A, N), I, M), r2([new1, I, N, A, Max]).
Clause Removal. The constraint ‘Z &gt; M, M = Z’ in the body of clause 12.1 is
unsatisfiable. Hence, this clause is removed from TranfP. By simplifying the
constraints in clause 12.2 we get:
14. new2(I1, N, A, M, K, Z) :- I1 = I+1, N = I1, K ≥ 0, K &lt; I, M &gt; Max, Z &gt; M,
read((A, N), K, Z), read((A, N), I, M), r2([new1, I, N, A, Max]).</p>
        <p>By applying similar goal replacements and clause removals, from clause 13 we
get:
15. new2(I1, N, A, Max, K, Z) :- I1 = I+1, N = I1, K ≥ 0, K &lt; I, M ≤ Max, Z &gt; Max,
read((A, N), K, Z), read((A, N), I, M), r2([new1, I, N, A, Max]).</p>
        <p>
          Definition &amp; Fold. In order to fold clause 14, we introduce the following
definition:
16. new3(I, N, A, Max, K, Z) :- K ≥ 0, K &lt; N, K &lt; I, Z &gt; Max, read((A, N), K, Z)),
r2([new1, I, N, A, Max]).
Clause 16 is obtained from clauses 10 and 14 by applying a generalization
operator called WidenSum [
          <xref ref-type="bibr" rid="ref17">17</xref>
          ], which is a variant of the classical widening
operator [
          <xref ref-type="bibr" rid="ref6">6</xref>
          ]. Clause 16 can be used also for folding clause 15, and by folding clauses 14
and 15 using clause 16, we get:
17. new2(I1, N, A, Max, K, Z) :- I1 = I+1, N = I1, K ≥ 0, K &lt; I, M &gt; Max, Z &gt; M,
read((A, N), I, M), new3(I, N, A, Max, K, Z).
18. new2(I1, N, A, M, K, Z) :- I1 = I+1, N = I1, K ≥ 0, K &lt; I, M ≤ Max, Z &gt; Max,
read((A, N), I, M), new3(I, N, A, Max, K, Z).
        </p>
        <p>Now we perform the third iteration of the body of the while-loop of the strategy.
After some unfolding, goal replacement, clause removal, and folding steps, from
clause 16 we get:
19. new3(I1, N, A, M, K, Z) :- I1 = I+1, K ≥ 0, K &lt; I, N ≥ I1, M &gt; Max, Z &gt; M,
read((A, N), I, M), new3(I, N, A, Max, K, Z).
20. new3(I1, N, A, Max, K, Z) :- I1 = I+1, K ≥ 0, K &lt; I, N ≥ I1, M ≤ Max, Z &gt; Max,
read((A, N), I, M), new3(I, N, A, Max, K, Z).</p>
        <p>Since we did not introduce any new definition, and no clause remains to be
processed (indeed, the set InDefs of definitions is empty), the Transform strategy
exits the while-loop and we get the program consisting of the set {11, 17, 18, 19, 20}
of clauses.</p>
        <p>Since no clause in this set is a constrained fact, by the final phase of removing
the useless clauses we get a final program consisting of the empty set of clauses.
Thus, the program ArrayMax is correct with respect to the given ϕinit and ϕerror
properties.
5</p>
      </sec>
    </sec>
    <sec id="sec-5">
      <title>Related Work and Conclusions</title>
      <p>
        The verification method presented in this paper is an extension of the one
introduced in [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ], where Constraint Logic Programming (CLP) and iterated
specialization have been used to define a general verification framework that is
parametric with respect to the programming language and the logic used for
specifying the correctness properties. The main novelties of this paper are the
following ones: (i) we have considered imperative programs acting on integer
variables as well as array variables, and (ii) we have allowed a more
expressive specification language, in which one can write properties about elements of
arrays and, in general, elements of complex data structures.
      </p>
      <p>
        In order to deal with this more general setting, we have defined the
operational semantics of array manipulation, and we have also considered powerful
transformation rules, such as conjunctive definition, conjunctive folding, and
goal replacement. These transformation rules together with some strategies for
guiding their application, have been implemented in the MAP transformation
system [
        <xref ref-type="bibr" rid="ref29">29</xref>
        ], so that the proofs of program correctness have been performed in a
semi-automatic way.
      </p>
      <p>
        The idea of encoding imperative programs into logic programs for reasoning
about the properties of those imperative programs is not novel. In particular,
for instance, this encoding has been recently used for reasoning about the type
system of Featherweight Java programs in [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ]. The use of constraint-based
techniques for program verification is not novel either.Indeed, CLP programs have
been successfully applied to perform model checking of both finite and infinite
state systems [
        <xref ref-type="bibr" rid="ref12 ref14 ref17">12, 14, 17</xref>
        ] because through CLP programs one can express in a
simple manner both (i) the symbolic executions of imperative programs and
(ii) the invariants which hold during their executions. Moreover, there are
powerful CLP-based tools, such as ARMC [
        <xref ref-type="bibr" rid="ref34">34</xref>
        ], TRACER [
        <xref ref-type="bibr" rid="ref22">22</xref>
        ], and HSF [
        <xref ref-type="bibr" rid="ref20">20</xref>
        ], that
can be used for performing model checking of imperative programs. These tools
are fully automatic, but they are applicable to classes of programs and
properties that are much more limited than those considered in this paper. We have
shown in [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ] that, by focusing on verification tasks similar to those considered by
ARMC, TRACER, and HSF, we can design a fully automatic,
transformationbased verification technique whose effectiveness is competitive to the one of the
above mentioned tools.
      </p>
      <p>
        Our rule-based program transformation technique is also related to
conjunctive partial deduction (CPD) [
        <xref ref-type="bibr" rid="ref11">11</xref>
        ], a technique for the specialization of logic
programs with respect to conjunctions of atoms. There are, however, some
substantial differences between CPD and the approach we have presented here.
First, CPD is not able to specialize logic programs with constraints and, thus,
it cannot be used to prove the correctness of the GCD program where the role
of constraints is crucial. Indeed, using the ECCE conjunctive partial deduction
system [
        <xref ref-type="bibr" rid="ref27">27</xref>
        ] for specializing the program consisting of clauses {3, 4, 5, 8r, 9,
10, 11r} with respect to the query incorrect, we obtain a residual program
where the predicate incorrect is not useless. Thus, we cannot conclude that
the atom incorrect does not belong to the least model of the program, and thus
we cannot conclude that the program is correct. One more difference between
CPD and our technique is that we may use goal replacement rules which allow
us to evaluate terms over domain-specific theories. In particular, we can apply
the goal replacement rules using well-developed theories for data structures like
arrays, lists, heaps and sets (see [
        <xref ref-type="bibr" rid="ref19 ref3 ref30 ref36 ref39 ref4">4, 30, 19, 3, 36, 39</xref>
        ] for some formalizations of
these theories).
      </p>
      <p>
        An alternative, systemic approach to program transformation is
supercompilation [
        <xref ref-type="bibr" rid="ref38">38</xref>
        ], which considers programs as machines. A supercompiler runs a
program and, while it observes its behavior, produces an equivalent program
without performing stepwise transformations of the original program.
      </p>
      <p>
        The verification method we have presented in this paper is also related to
several other methods for verifying properties of imperative programs acting on
arrays. Those methods use techniques based on abstract interpretation, theorem
proving and, in particular, Satisfiability Modulo Theory (see, for instance, [
        <xref ref-type="bibr" rid="ref25 ref26 ref7">7,
25, 26</xref>
        ]).
      </p>
      <p>
        The application of the powerful transformation rules we have considered in
this paper enables us to verify larger classes of properties, but the strategies to
be applied for dealing with those classes are not all instances of the automated
strategy introduced in [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ].
In the future we intend to consider the issue of designing fully mechanizable
strategies for guiding the application of our program transformation rules. In
particular, we want to study the problem of devising suitable unfolding strategies
and generalization operators, by adapting the techniques already developed for
program transformation. We also envisage that the application of the laws used
by the goal replacement rule can be automated by importing in our framework
the techniques used in the fields of Theorem Proving and Term Rewriting. For
some specific theories we could also apply the goal replacement rule by exploiting
the results obtained by external theorem provers or Satisfiability Modulo Theory
solvers.
      </p>
      <p>We also plan to address the issue of proving correctness of programs acting
on dynamic data structures such as lists or heaps, looking for a set of suitable
goal replacement laws which axiomatize those structures.</p>
    </sec>
    <sec id="sec-6">
      <title>Acknowledgements</title>
      <p>We would like to thank the anonymous referees for their helpful comments and
constructive criticism.</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          1.
          <string-name>
            <given-names>D.</given-names>
            <surname>Ancona</surname>
          </string-name>
          and
          <string-name>
            <given-names>G.</given-names>
            <surname>Lagorio</surname>
          </string-name>
          .
          <article-title>Coinductive Type Systems for Object-Oriented Languages</article-title>
          .
          <source>In Proceedings of the 23th European Conference on Object-Oriented Programming. ECOOP'09, Lecture Notes in Computer Science</source>
          <volume>5653</volume>
          , pages
          <fpage>2</fpage>
          -
          <lpage>26</lpage>
          . Springer,
          <year>2009</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          2.
          <string-name>
            <given-names>D.</given-names>
            <surname>Beyer</surname>
          </string-name>
          ,
          <string-name>
            <given-names>T. A.</given-names>
            <surname>Henzinger</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R.</given-names>
            <surname>Majumdar</surname>
          </string-name>
          ,
          <article-title>and</article-title>
          <string-name>
            <given-names>A.</given-names>
            <surname>Rybalchenko</surname>
          </string-name>
          .
          <article-title>Invariant synthesis for combined theories</article-title>
          .
          <source>In Proceedings of the 8th International Conference on Verification, Model Checking, and Abstract Interpretation. VMCAI'07 , Lecture Notes in Computer Science</source>
          <volume>4349</volume>
          , pages
          <fpage>378</fpage>
          -
          <lpage>394</lpage>
          . Springer,
          <year>2007</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          3.
          <string-name>
            <given-names>R. S.</given-names>
            <surname>Bird</surname>
          </string-name>
          .
          <article-title>An introduction to the theory of lists</article-title>
          .
          <source>In Proceedings of the NATO Advanced Study Institute on Logic of programming and calculi of discrete design</source>
          , pages
          <fpage>5</fpage>
          -
          <lpage>42</lpage>
          . Springer-Verlag New York, Inc.,
          <year>1987</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          4.
          <string-name>
            <given-names>A. R.</given-names>
            <surname>Bradley</surname>
          </string-name>
          ,
          <string-name>
            <given-names>Z.</given-names>
            <surname>Manna</surname>
          </string-name>
          , and
          <string-name>
            <given-names>H. B.</given-names>
            <surname>Sipma</surname>
          </string-name>
          .
          <article-title>What's decidable about arrays</article-title>
          ?
          <source>In Proceedings of the 7th International Conference on Verification, Model Checking, and Abstract Interpretation. VMCAI'06</source>
          ,
          <string-name>
            <surname>Charleston</surname>
            ,
            <given-names>SC</given-names>
          </string-name>
          , USA, Lecture Notes in Computer Science 3855. Springer,
          <year>2006</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          5.
          <string-name>
            <given-names>R. M.</given-names>
            <surname>Burstall</surname>
          </string-name>
          and
          <string-name>
            <given-names>J.</given-names>
            <surname>Darlington</surname>
          </string-name>
          .
          <article-title>A transformation system for developing recursive programs</article-title>
          .
          <source>Journal of the ACM</source>
          ,
          <volume>24</volume>
          (
          <issue>1</issue>
          ):
          <fpage>44</fpage>
          -
          <lpage>67</lpage>
          ,
          <year>1977</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          6.
          <string-name>
            <given-names>P.</given-names>
            <surname>Cousot</surname>
          </string-name>
          and
          <string-name>
            <given-names>R.</given-names>
            <surname>Cousot</surname>
          </string-name>
          .
          <article-title>Abstract interpretation: A unified lattice model for static analysis of programs by construction of approximation of fixpoints</article-title>
          .
          <source>In Proceedings of the 4th ACM-SIGPLAN Symposium on Principles of Programming Languages, POPL'77</source>
          , pages
          <fpage>238</fpage>
          -
          <lpage>252</lpage>
          . ACM Press,
          <year>1977</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          7.
          <string-name>
            <given-names>P.</given-names>
            <surname>Cousot</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R.</given-names>
            <surname>Cousot</surname>
          </string-name>
          , and
          <string-name>
            <given-names>F.</given-names>
            <surname>Logozzo</surname>
          </string-name>
          .
          <article-title>A parametric segmentation functor for fully automatic and scalable array content analysis</article-title>
          .
          <source>In Proceedings of the 38th ACM Symposium on Principles of programming languages. POPL'11</source>
          , pages
          <fpage>105</fpage>
          -
          <lpage>118</lpage>
          ,
          <year>2011</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          8.
          <string-name>
            <given-names>P.</given-names>
            <surname>Cousot</surname>
          </string-name>
          and
          <string-name>
            <given-names>N.</given-names>
            <surname>Halbwachs</surname>
          </string-name>
          .
          <article-title>Automatic discovery of linear restraints among variables of a program</article-title>
          .
          <source>In Proceedings of the Fifth ACM Symposium on Principles of Programming Languages, POPL'78</source>
          , pages
          <fpage>84</fpage>
          -
          <lpage>96</lpage>
          . ACM Press,
          <year>1978</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          9.
          <string-name>
            <surname>E. De Angelis</surname>
            ,
            <given-names>F.</given-names>
          </string-name>
          <string-name>
            <surname>Fioravanti</surname>
            ,
            <given-names>A.</given-names>
          </string-name>
          <string-name>
            <surname>Pettorossi</surname>
            , and
            <given-names>M.</given-names>
          </string-name>
          <string-name>
            <surname>Proietti</surname>
          </string-name>
          .
          <article-title>Verifying Programs via Iterated Specialization</article-title>
          .
          <source>In Proceedings of the ACM SIGPLAN 2013 Workshop on Partial Evaluation and Program Manipulation</source>
          ,
          <source>PEPM'13</source>
          , pages
          <fpage>43</fpage>
          -
          <lpage>52</lpage>
          ,
          <year>2013</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          10.
          <string-name>
            <surname>E. De Angelis</surname>
            ,
            <given-names>F.</given-names>
          </string-name>
          <string-name>
            <surname>Fioravanti</surname>
            ,
            <given-names>A.</given-names>
          </string-name>
          <string-name>
            <surname>Pettorossi</surname>
            , and
            <given-names>M.</given-names>
          </string-name>
          <string-name>
            <surname>Proietti</surname>
          </string-name>
          .
          <article-title>Verification of Imperative Programs by Constraint Logic Program Transformation</article-title>
          . In Semantics, Abstract Interpretation, and
          <article-title>Reasoning about Programs</article-title>
          ,
          <source>SAIRP'13, EPTCS 129</source>
          , pages
          <fpage>186</fpage>
          -
          <lpage>210</lpage>
          ,
          <year>2013</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          11.
          <string-name>
            <surname>D. De Schreye</surname>
            ,
            <given-names>R.</given-names>
          </string-name>
          <string-name>
            <surname>Glück</surname>
            ,
            <given-names>J.</given-names>
          </string-name>
          <string-name>
            <surname>Jørgensen</surname>
            ,
            <given-names>M.</given-names>
          </string-name>
          <string-name>
            <surname>Leuschel</surname>
            ,
            <given-names>B.</given-names>
          </string-name>
          <string-name>
            <surname>Martens</surname>
            , and
            <given-names>M. H.</given-names>
          </string-name>
          <string-name>
            <surname>Sørensen</surname>
          </string-name>
          .
          <article-title>Conjunctive partial deduction: Foundations, control, algorithms, and experiments</article-title>
          .
          <source>Journal of Logic Programming</source>
          ,
          <volume>41</volume>
          (
          <issue>2-3</issue>
          ):
          <fpage>231</fpage>
          -
          <lpage>277</lpage>
          ,
          <year>1999</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref12">
        <mixed-citation>
          12.
          <string-name>
            <given-names>G.</given-names>
            <surname>Delzanno</surname>
          </string-name>
          and
          <string-name>
            <given-names>A.</given-names>
            <surname>Podelski</surname>
          </string-name>
          .
          <article-title>Model checking in CLP</article-title>
          . In R. Cleaveland, ed.,
          <source>5th International Conference on Tools and Algorithms for the Construction and Analysis of Systems, TACAS'99, Lecture Notes in Computer Science</source>
          <volume>1579</volume>
          , pages
          <fpage>223</fpage>
          -
          <lpage>239</lpage>
          . Springer-Verlag,
          <year>1999</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref13">
        <mixed-citation>
          13.
          <string-name>
            <given-names>S.</given-names>
            <surname>Etalle</surname>
          </string-name>
          and
          <string-name>
            <given-names>M.</given-names>
            <surname>Gabbrielli</surname>
          </string-name>
          .
          <article-title>Transformations of CLP modules</article-title>
          .
          <source>Theoretical Computer Science</source>
          ,
          <volume>166</volume>
          :
          <fpage>101</fpage>
          -
          <lpage>146</lpage>
          ,
          <year>1996</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref14">
        <mixed-citation>
          14.
          <string-name>
            <given-names>F.</given-names>
            <surname>Fioravanti</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Pettorossi</surname>
          </string-name>
          , and
          <string-name>
            <given-names>M.</given-names>
            <surname>Proietti</surname>
          </string-name>
          .
          <article-title>Verifying CTL properties of infinite state systems by specializing constraint logic programs</article-title>
          .
          <source>In Proceedings of the ACM SIGPLAN Workshop on Verification and Computational Logic VCL'01</source>
          ,
          <string-name>
            <surname>Florence</surname>
          </string-name>
          , Italy,
          <source>Technical Report DSSE-TR-2001-3</source>
          , pages
          <fpage>85</fpage>
          -
          <lpage>96</lpage>
          . University of Southampton, UK,
          <year>2001</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref15">
        <mixed-citation>
          15.
          <string-name>
            <given-names>F.</given-names>
            <surname>Fioravanti</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Pettorossi</surname>
          </string-name>
          , and
          <string-name>
            <given-names>M.</given-names>
            <surname>Proietti</surname>
          </string-name>
          .
          <article-title>Transformation Rules for Locally Stratified Constraint Logic Programs</article-title>
          . In K.
          <article-title>-</article-title>
          K. Lau and M. Bruynooghe, eds Program Development in
          <source>Computational Logic, Lecture Notes in Computer Science</source>
          <volume>3049</volume>
          , pages
          <fpage>292</fpage>
          -
          <lpage>340</lpage>
          . Springer,
          <year>2004</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref16">
        <mixed-citation>
          16.
          <string-name>
            <given-names>F.</given-names>
            <surname>Fioravanti</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Pettorossi</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Proietti</surname>
          </string-name>
          , and
          <string-name>
            <given-names>V.</given-names>
            <surname>Senni</surname>
          </string-name>
          .
          <article-title>Improving reachability analysis of infinite state systems by specialization</article-title>
          . In G. Delzanno and I. Potapov, eds.,
          <source>Proceedings of the 5th International Workshop on Reachability Problems</source>
          , RP'11,
          <string-name>
            <surname>Genoa</surname>
          </string-name>
          ,
          <source>Italy, Lecture Notes in Computer Science</source>
          <volume>6945</volume>
          , pages
          <fpage>165</fpage>
          -
          <lpage>179</lpage>
          . Springer,
          <year>2011</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref17">
        <mixed-citation>
          17.
          <string-name>
            <given-names>F.</given-names>
            <surname>Fioravanti</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Pettorossi</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Proietti</surname>
          </string-name>
          , and
          <string-name>
            <given-names>V.</given-names>
            <surname>Senni</surname>
          </string-name>
          .
          <article-title>Generalization strategies for the verification of infinite state systems</article-title>
          .
          <source>Theory and Practice of Logic Programming</source>
          .
          <source>Special Issue on the 25th Annual GULP Conference</source>
          ,
          <volume>13</volume>
          (
          <issue>2</issue>
          ):
          <fpage>175</fpage>
          -
          <lpage>199</lpage>
          ,
          <year>2013</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref18">
        <mixed-citation>
          18.
          <string-name>
            <given-names>C.</given-names>
            <surname>Flanagan</surname>
          </string-name>
          .
          <article-title>Automatic software model checking via constraint logic</article-title>
          .
          <source>Sci. Comput</source>
          . Program.,
          <volume>50</volume>
          (
          <issue>1-3</issue>
          ):
          <fpage>253</fpage>
          -
          <lpage>270</lpage>
          ,
          <year>2004</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref19">
        <mixed-citation>
          19.
          <string-name>
            <given-names>S.</given-names>
            <surname>Ghilardi</surname>
          </string-name>
          ,
          <string-name>
            <given-names>E.</given-names>
            <surname>Nicolini</surname>
          </string-name>
          ,
          <string-name>
            <given-names>S.</given-names>
            <surname>Ranise</surname>
          </string-name>
          , and
          <string-name>
            <given-names>D.</given-names>
            <surname>Zucchelli</surname>
          </string-name>
          .
          <article-title>Decision procedures for extensions of the theory of arrays</article-title>
          . Ann. Math. Artif. Intell.,
          <volume>50</volume>
          (
          <issue>3-4</issue>
          ):
          <fpage>231</fpage>
          -
          <lpage>254</lpage>
          ,
          <year>2007</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref20">
        <mixed-citation>
          20.
          <string-name>
            <given-names>S.</given-names>
            <surname>Grebenshchikov</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Gupta</surname>
          </string-name>
          ,
          <string-name>
            <given-names>N. P.</given-names>
            <surname>Lopes</surname>
          </string-name>
          ,
          <string-name>
            <given-names>C.</given-names>
            <surname>Popeea</surname>
          </string-name>
          ,
          <article-title>and</article-title>
          <string-name>
            <given-names>A.</given-names>
            <surname>Rybalchenko. HSF(C):</surname>
          </string-name>
          <article-title>A Software Verifier based on Horn Clauses</article-title>
          .
          <source>In Proc. of the 18th International Conference on Tools and Algorithms for the Construction and Analysis of Systems, TACAS'12, Lecture Notes in Computer Science</source>
          <volume>7214</volume>
          , pages
          <fpage>549</fpage>
          -
          <lpage>551</lpage>
          . Springer,
          <year>2012</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref21">
        <mixed-citation>
          21.
          <string-name>
            <given-names>J.</given-names>
            <surname>Jaffar</surname>
          </string-name>
          and
          <string-name>
            <given-names>M.</given-names>
            <surname>Maher</surname>
          </string-name>
          .
          <article-title>Constraint logic programming: A survey</article-title>
          .
          <source>Journal of Logic Programming</source>
          ,
          <volume>19</volume>
          /20:
          <fpage>503</fpage>
          -
          <lpage>581</lpage>
          ,
          <year>1994</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref22">
        <mixed-citation>
          22.
          <string-name>
            <surname>J. Jaffar</surname>
            ,
            <given-names>V.</given-names>
          </string-name>
          <string-name>
            <surname>Murali</surname>
            ,
            <given-names>J. A.</given-names>
          </string-name>
          <string-name>
            <surname>Navas</surname>
          </string-name>
          ,
          <article-title>and</article-title>
          <string-name>
            <surname>A. E. Santosa.</surname>
          </string-name>
          <article-title>TRACER: A symbolic execution tool for verification</article-title>
          .
          <source>In CAV'12, Lecture Notes in Computer Science</source>
          <volume>7358</volume>
          , pages
          <fpage>758</fpage>
          -
          <lpage>766</lpage>
          . Springer,
          <year>2012</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref23">
        <mixed-citation>
          23.
          <string-name>
            <given-names>R.</given-names>
            <surname>Jhala</surname>
          </string-name>
          and
          <string-name>
            <given-names>R.</given-names>
            <surname>Majumdar</surname>
          </string-name>
          .
          <article-title>Software model checking</article-title>
          .
          <source>ACM Computing Surveys</source>
          ,
          <volume>41</volume>
          (
          <issue>4</issue>
          ):
          <volume>21</volume>
          :
          <fpage>1</fpage>
          -
          <lpage>21</lpage>
          :
          <fpage>54</fpage>
          ,
          <year>2009</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref24">
        <mixed-citation>
          24.
          <string-name>
            <given-names>N. D.</given-names>
            <surname>Jones</surname>
          </string-name>
          ,
          <string-name>
            <given-names>C. K.</given-names>
            <surname>Gomard</surname>
          </string-name>
          , and
          <string-name>
            <given-names>P.</given-names>
            <surname>Sestoft</surname>
          </string-name>
          .
          <article-title>Partial Evaluation and Automatic Program Generation</article-title>
          . Prentice Hall,
          <year>1993</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref25">
        <mixed-citation>
          25.
          <string-name>
            <given-names>L.</given-names>
            <surname>Kovács</surname>
          </string-name>
          and
          <string-name>
            <given-names>A.</given-names>
            <surname>Voronkov</surname>
          </string-name>
          .
          <article-title>Finding loop invariants for programs over arrays using a theorem prover</article-title>
          .
          <source>In Proceedings of the 12th International Conference on Fundamental Approaches to Software Engineering. FASE'09, Lecture Notes in Computer Science</source>
          <volume>5503</volume>
          , pages
          <fpage>470</fpage>
          -
          <lpage>485</lpage>
          . Springer,
          <year>2009</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref26">
        <mixed-citation>
          26.
          <string-name>
            <given-names>D.</given-names>
            <surname>Larraz</surname>
          </string-name>
          , E. Rodríguez-Carbonell,
          <article-title>and</article-title>
          <string-name>
            <given-names>A.</given-names>
            <surname>Rubio</surname>
          </string-name>
          .
          <article-title>SMT-based array invariant generation</article-title>
          .
          <source>In 14th International Conference on Verification, Model Checking, and Abstract Interpretation</source>
          ,
          <source>VMCAI'13</source>
          , Rome, Italy, Lecture Notes in Computer Science 7737, pages
          <fpage>169</fpage>
          -
          <lpage>188</lpage>
          . Springer,
          <year>2013</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref27">
        <mixed-citation>
          27.
          <string-name>
            <given-names>M.</given-names>
            <surname>Leuschel</surname>
          </string-name>
          .
          <article-title>The ECCE partial deduction system and the DPPD library of benchmarks, Release 3</article-title>
          ,
          <string-name>
            <surname>Nov</surname>
          </string-name>
          .
          <year>2000</year>
          . Available from http://www.ecs.soton.ac.uk/∼mal.
        </mixed-citation>
      </ref>
      <ref id="ref28">
        <mixed-citation>
          28.
          <string-name>
            <given-names>M.</given-names>
            <surname>Leuschel</surname>
          </string-name>
          and
          <string-name>
            <given-names>M.</given-names>
            <surname>Bruynooghe</surname>
          </string-name>
          .
          <article-title>Logic program specialisation through partial deduction: Control issues</article-title>
          .
          <source>Theory and Practice of Logic Programming</source>
          ,
          <volume>2</volume>
          (
          <issue>4</issue>
          &amp;5):
          <fpage>461</fpage>
          -
          <lpage>515</lpage>
          ,
          <year>2002</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref29">
        <mixed-citation>
          29.
          <string-name>
            <surname>MAP</surname>
          </string-name>
          <article-title>: The MAP transformation system</article-title>
          . http://www.iasi.cnr.it/∼proietti/ system.html. Via a WEB interface: http://www.map.uniroma2.it/mapweb.
        </mixed-citation>
      </ref>
      <ref id="ref30">
        <mixed-citation>
          30.
          <string-name>
            <surname>J. McCarthy</surname>
          </string-name>
          .
          <article-title>A basis for a mathematical theory of computation</article-title>
          .
          <source>In Computer Programming and Formal Systems</source>
          , pages
          <fpage>33</fpage>
          -
          <lpage>70</lpage>
          . North-Holland,
          <year>1963</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref31">
        <mixed-citation>
          31.
          <string-name>
            <surname>J. McCarthy</surname>
          </string-name>
          .
          <article-title>Towards a mathematical science of computation</article-title>
          . In C. Popplewell, ed.,
          <source>Information Processing. Proceedings of IFIP 1962</source>
          , pages
          <fpage>21</fpage>
          -
          <lpage>28</lpage>
          , Amsterdam,
          <year>1963</year>
          . North Holland.
        </mixed-citation>
      </ref>
      <ref id="ref32">
        <mixed-citation>
          32.
          <string-name>
            <given-names>J. C.</given-names>
            <surname>Peralta</surname>
          </string-name>
          and
          <string-name>
            <given-names>J. P.</given-names>
            <surname>Gallagher</surname>
          </string-name>
          .
          <article-title>Convex hull abstractions in specialization of CLP programs</article-title>
          . In M. Leuschel, ed.,
          <source>Logic Based Program Synthesis and Tranformation</source>
          , 12th International Workshop, LOPSTR'
          <fpage>02</fpage>
          , Madrid, Spain,
          <source>Revised Selected Papers, Lecture Notes in Computer Science</source>
          <volume>2664</volume>
          , pages
          <fpage>90</fpage>
          -
          <lpage>108</lpage>
          ,
          <year>2003</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref33">
        <mixed-citation>
          33.
          <string-name>
            <surname>J. C. Peralta</surname>
            ,
            <given-names>J. P.</given-names>
          </string-name>
          <string-name>
            <surname>Gallagher</surname>
            , and
            <given-names>H.</given-names>
          </string-name>
          <string-name>
            <surname>Saglam</surname>
          </string-name>
          .
          <article-title>Analysis of Imperative Programs through Analysis of Constraint Logic Programs</article-title>
          . In G. Levi, ed.,
          <source>Static Analysis, 5th International Symposium</source>
          , SAS'98,
          <string-name>
            <surname>Pisa</surname>
          </string-name>
          ,
          <source>Italy, Lecture Notes in Computer Science</source>
          <volume>1503</volume>
          , pages
          <fpage>246</fpage>
          -
          <lpage>261</lpage>
          . Springer,
          <year>1998</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref34">
        <mixed-citation>
          34.
          <string-name>
            <given-names>A.</given-names>
            <surname>Podelski</surname>
          </string-name>
          and
          <string-name>
            <given-names>A.</given-names>
            <surname>Rybalchenko</surname>
          </string-name>
          .
          <article-title>ARMC: The Logical Choice for Software Model Checking with Abstraction Refinement</article-title>
          . In M. Hanus, ed.,
          <source>Practical Aspects of Declarative Languages, PADL'07, Lecture Notes in Computer Science</source>
          <volume>4354</volume>
          , pages
          <fpage>245</fpage>
          -
          <lpage>259</lpage>
          . Springer,
          <year>2007</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref35">
        <mixed-citation>
          35.
          <string-name>
            <surname>C. J. Reynolds</surname>
          </string-name>
          .
          <source>Theories of Programming Languages</source>
          . Cambridge University Press,
          <year>1998</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref36">
        <mixed-citation>
          36.
          <string-name>
            <surname>J. C.</surname>
          </string-name>
          <article-title>Reynolds. Separation logic: A logic for shared mutable data structures</article-title>
          .
          <source>In Proceedings of the 17th Annual IEEE Symposium on Logic in Computer Science LICS'02</source>
          , pages
          <fpage>55</fpage>
          -
          <lpage>74</lpage>
          . IEEE Computer Society,
          <year>2002</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref37">
        <mixed-citation>
          37.
          <string-name>
            <given-names>H.</given-names>
            <surname>Tamaki</surname>
          </string-name>
          and
          <string-name>
            <given-names>T.</given-names>
            <surname>Sato</surname>
          </string-name>
          .
          <article-title>Unfold/fold transformation of logic programs</article-title>
          . In S.-Å. Tärnlund, ed.,
          <source>Proceedings of the Second International Conference on Logic Programming</source>
          ,
          <source>ICLP'84</source>
          , pages
          <fpage>127</fpage>
          -
          <lpage>138</lpage>
          , Uppsala, Sweden,
          <year>1984</year>
          . Uppsala University.
        </mixed-citation>
      </ref>
      <ref id="ref38">
        <mixed-citation>
          38.
          <string-name>
            <given-names>V. F.</given-names>
            <surname>Turchin</surname>
          </string-name>
          .
          <article-title>The concept of a supercompiler</article-title>
          .
          <source>ACM TOPLAS</source>
          ,
          <volume>8</volume>
          (
          <issue>3</issue>
          ):
          <fpage>292</fpage>
          -
          <lpage>325</lpage>
          ,
          <year>1986</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref39">
        <mixed-citation>
          39.
          <string-name>
            <given-names>M.</given-names>
            <surname>Wirsing</surname>
          </string-name>
          .
          <article-title>Algebraic specification</article-title>
          . In J. Van Leeuwen, ed.,
          <source>Handbook of Theoretical Computer Science</source>
          , volume B, pages
          <fpage>675</fpage>
          -
          <lpage>788</lpage>
          . Elsevier,
          <year>1990</year>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>