Scholarly article on topic 'Declarative Debugging of Functional Logic Programs1 1This work has been partially supported by CICYT under grant TIC2001-2705-C03-01, by Accóon Integrada Hispano-Italiana HI2000-0161 and by Generalitat Valenciana under grant GV01-424.'

Declarative Debugging of Functional Logic Programs1 1This work has been partially supported by CICYT under grant TIC2001-2705-C03-01, by Accóon Integrada Hispano-Italiana HI2000-0161 and by Generalitat Valenciana under grant GV01-424. Academic research paper on "Computer and information sciences"

Share paper

Abstract of research paper on Computer and information sciences, author of scientific article — M. Alpuente, F.J. Correa, M. Falaschi

Abstract We present a general framework for the declarative debugging of functional logic programs, which is valid both for eager as well as lazy programs. We associate to our programs a semantics based on a (continuous) immediate consequence operator which models computed answers. Then we show that, given the intended specification of a program P, it is possible to check the correctness of P by a single step of the immediate consequence operator. We also present a more effective methodology which is based on abstract interpretation. By approximating the intended specification of the success set we derive a finitely terminating debugging method, which can be used statically. Our framework is parametric w.r.t. to the chosen approximation of the success set. We present one specific example of approximation. We provide an implementation of our debugging system which shows experimentally on a wide set of benchmarks that we are able to find some common errors in the user programs.

Academic research paper on topic "Declarative Debugging of Functional Logic Programs1 1This work has been partially supported by CICYT under grant TIC2001-2705-C03-01, by Accóon Integrada Hispano-Italiana HI2000-0161 and by Generalitat Valenciana under grant GV01-424."

Electronic Notes in Theoretical Computer Science 57 (2001)

URL: 24 pages

Declarative Debugging of

Functional Logic Programs

M. Alpuente2

Departamento de Sistemas Inform,áticos y Computación-DSIC Technical University of Valencia

Camino de Vera s/n, 46022 Valencia, Spain.

F. J. Correa

Departamento de Informática y Sistemas-DIS University EAFIT, Carrera 49 1 Sur 50, 3300 Medellín, Colombia.

M. Falaschí4

Dipartimento di Matematica e Informática University of Udine, Via delle Scienze 206, 33100 Udine, Italy.


We present a general framework for the declarative debugging of functional logic programs, which is valid both for eager as well as lazy programs. We associate to our programs a semantics based on a (continuous) immediate consequence operator which models computed answers. Then we show that, given the intended specification of a program P, it is possible to check the correctness of P by a single step of the immediate consequence operator.

We also present a more effective methodology which is based on abstract interpretation. By approximating the intended specification of the success set we derive a finitely terminating debugging method, which can be used statically. Our framework is parametric w.r.t. to the chosen approximation of the success set. We present one specific example of approximation. We provide an implementation of our debugging system which shows experimentally on a wide set of benchmarks that we are able to find some common errors in the user programs.

©2001 Published by Elsevier Science B. V.

1 Introduction

Declarative programming is supported both by functional and logic programming, However, each of these programming styles has different advantages w.r.t, practical applications. Functional languages provide sophisticated abstraction facilities, module systems and clean solutions for integrating I/O into declarative programming as well as for efficient program execution. Logic languages allow for computing with partial information and provide built-in search facilities which have strong applications for knowledge-based systems and operations research. However, recent results show that the advantages of these styles can be efficiently and usefully combined into a single language. Modern functional logic languages offer features from both styles. The operational semantics of integrated languages is usually based on narrowing, a combination of unification for parameter passing and reduction as evaluation mechanism which subsumes rewriting and SLD-resolution, Essentially, narrowing consists of the instantiation of goal variables, followed by a reduction step on the instantiated goal. Narrowing is complete in the sense of functional programming (computation of normal forms) as well as logic programming (computation of answers). Due to the huge search space of unrestricted narrowing, steadily improved strategies have been proposed (see [29] for a survey.)

How to debug functional logic programs is an important practical problem which has hardly been addressed in the previous literature. Only a few functional logic languages are equipped with a debugging tool (e.g. ALF [28], Babel [39] and Curry [31]), However, these debuggers consist of tracers which are based on suitable extended box models which help display the execution [30,5], Due to the complexity of the operational semantics of (functional) logic programs, the information obtained by tracing the execution is difficult to understand. The functional logic programming language NUE-Prolog is endowed with a declarative debugger [40] which works in the style proposed by Shapiro [43], that is, an oracle (typically the user) is supposed to endow the debugger with error symptoms, as well as to correctly answer oracle questions driven by proof trees aimed at locating the actual source of errors, A similar declarative debugger for the functional logic language Escher is proposed in [36], Following the generic scheme which is based on proof trees of [41], a procedure for the declarative debugging of wrong answers is given in [12] for lazy functional logic languages. The methodology in [12] includes a formalization of computation trees which is precise enough to prove the logical correctness for the debugger and which also helps simplify oracle questions.

In the case of pure logic programming, [17] has defined a declarative fra-

1 This work has been partially supported by CICYT under grant TIC2001-2705-C03-01, by Acción Integrada Hispan o-Italiana HI2000-0161 and by Generalitat Valenciana under grant GV01-424.

2 Email:

3 Email:

4 Email: falaschi0dimi .uniud. it

mework for debugging which extends the methodology in [25,43] to diagnosis w.r.t, computed answers. The framework does not require the determination the symptoms in advance and is goal independent -it is driven by a set of most general atomic goals. It is based on using the immediate consequences operator TP to identify program bugs and has the advantage of giving a symptom-independent diagnosis method [17,16],

In this paper, one of the contributions is to develop a declarative diagnosis method w.r.t, computed answers which generalizes the ideas of [17] to the diagnosis of functional logic programs. The conditions which we impose on the programs which we consider allow us to define a framework for declarative debugging which works for both eager (call-by-value) narrowing as well as for lazy (call-by-name) narrowing. We associate a (continuous) immediate consequence operator to our programs. Then we show that, given the intended specification X of a program 7Z, we can check the correctness of 1Z by a single step of this operator. We illustrate this through examples. We discuss the use of our work for both bottom-up as well as top-down abstract debugging of mixed functional logic code.

We also present a novel, efficient methodology which is based on abstract interpretation. We proceed by approximating the intended specification of the success set. Following an idea inspired in [17,16,11], we use over and under specifications Z+ and X- to correctly over- (resp. under-) approximate the intended semantics. We then use these two sets respectively for the functions in the premises and the consequence of the immediate consequence operator, and by a simple static test we can determine whether some of the clauses are wrong.

1.1 Plan of the paper

The rest of the paper is organized as follows. Section 2 briefly presents some preliminary definitions and notations. Section 3 first formulates a novel, generic immediate consequence operator for functional logic program 1Z which is parametric w.r.t. the narrowing strategy tp which can be either eager or lazy. We then define a fixpoint semantics based on T^ which correctly models the answers computed by a narrower which uses the narrowing strategy tp. In the case of the eager strategy, it is enough to introduce a flattening transformation which eliminates nesting calls and allows goals to run in the semantics by standard unification. However, the lazy strategy is more involved and we need to introduce two kinds of equality in the definition of T^: the strict equality which « models the equality on data terms, and the non-strict = which holds even if the arguments are both undefined or partially defined, similarly to [27]. We also formulate a semantics Ov( 1Z) and we show the correspondence with the fixpoint semantics. In section 4, we introduce the necessary general notions of incorrectness and insufficiency symptoms and uncovered calls. Section 5 provides an abstract semantics which correctly approximates the fixpoint

semantics of 7Z. In Section 6, we present our method of abstract diagnosis and illustrate its use through examples. In Section 7, we present an experimental evaluation of the method on a set of benchmarks. Section 8 concludes and discusses some related work,

2 Preliminaries

We briefly summarize some known results about rewrite systems [6,34] and functional logic programming (see [29,33] for extensive surveys). Throughout this paper, V will denote a countablv infinite set of variables and £ denotes a set of function symbols, or signature, each of which has a fixed associated aritv, r(E U V) and r(E) denote the non-ground word (or term) algebra and the word algebra built on £ U V and £, respectively, r(E) is usually called the Herbrand universe (He) over £ and it will be denoted by %. B denotes the Herbrand base, namely the set of all ground equations which can be built with the elements of %. A E-equation s = t is a pair of terms s,t E r(E U V).

Terms are viewed as labelled trees in the usual way. Positions are represented by sequences of natural numbers denoting an access path in a term, where A denotes the empty sequence, 0(t) denotes the set of nonvariable positions of a term t. t\u is the subterm at the position u of t. t[r]u is the term t with the subterm at the position u replaced with r. These notions extend to sequences of equations in a natural way. For instance, the nonvariable position set of a sequence of equations g = (ei,... ,en) can be defined as follows: 0(g) = {i.u \ u E 0(ei),i = 1,,,, , n}, By Var(s) we denote the set of variables occurring in the syntactic object s, while [s] denotes the set of ground instances of s. A fresh variable is a variable that appears nowhere else. The symbol ~ denotes a finite sequence of symbols. Identity of syntactic objects is denoted by =,

Let Eqn denote the set of possibly existentiallv quantified finite sets of equations over terms [14], We write E < E' if E' logically implies E. Thus Eqn is a lattice ordered by < with bottom element true and top element fail. The elements of Eqn are regarded as (quantified) conjunctions of equations and treated modulo logical equivalence. An equation set is solved if it is either fail or it has the form 3?ji... 3ym. {xi = ti,...,xn = tn}, where each Xjt is a distinct variable not occurring in any of the terms ti and each Hi occurs in some tj. Any set of equations E can be transformed into an equivalent one, solve(E), which is solved. We restrict our interest to the set of idempotent substitutions over r(E U V), which is denoted by Sub. The empty substitution is denoted by e. There is a natural isomorphism between substitutions 9 = {xi/ti,..., xn/tn} and unquantified equation sets 9 = {xi = ti,...,xn = tn}. A substitution 9 = {xi/ti,... ,xn/tn} is a unifier of an equation set /•.' id' 9 /•.'. We let mgu(E) denote the most general unifier of the unquantified equation set E. We write mgu({si = ti,..., sn = tn}, {s^ = ti,,,,, sn = tn }) to denote the most general unifier of the set of equations

{si = -v'. ti = t[,..., sn = s'n, I„ = /', }■. We write 0-s to denote the restriction of the substitution 9 to the set of variables in the syntactic object s.

A conditional term rewriting system (CTRS for short) is a pair (J2,7Z), where 7Z is a finite set of reduction (or rewrite) rule schemes of the form (A —p 4= C), A, p E t(£ U V), A 0 V and Var(p) C Var(X). The condition

C is a (possibly empty) sequence n.....<•„. n > 0, of equations which we

handle as a set (conjunction) when we find it convenient. Variables in C that do not occur in A are called extra-variables. We will often write just 1Z instead of (E,1Z). If a rewrite rule has no condition, we write A —t p. For CTRS 7Z, r C 1Z denotes that r is a new variant of a rule in 1Z such that r contains only fresh variables, i.e. contains no variable previously met during computation (standardized apart). Given a CTRS (E,7Z), we assume that the signature £ is partitioned into two disjoint sets £ = C W V, where V = {/ I (/(f) ^ r n e R\ and C = \\V. Symbols in C are called constructors and symbols in V are called defined functions.

A rewrite step is the application of a rewrite rule to an expression, A term s conditionally rewrites to a term t, s ^¡-n t, if there exist u E O(s), (A —p <= Si = ti,..., sn = tn) e 1Z, and substitution o such that S|M = Aa, t = s[pa]u, and for all i E {1,..., n} there exists a term Wi such that Si Wi and ti ^^ Wi, where ^^ is the transitive and reflexive closure of ^-n- When no confusion can arise, we omit the subscript 1Z. A term s is a normal form., if there is no term t with s t. The program 1Z is said to be canonical if the binary one-step rewriting relation defined by 7Z is noetherian and confluent [34],

An equational Horn theory £ consists of a finite set of equational Horn clauses of the form (A = p) C. An equational goal is a sequence of equations C, i.e. an equational Horn clause with no head. We usually leave out the symbol when we write goals, A goal of the form x = y, with x, y E V is called a trivial goal. A Horn equational theory 8, satisfying A 0 V and Var(p) C For (A) for each clause (A = p) C, can be viewed as a CTRS 7Z, where the rules are the heads (implicitly oriented from left to right) and the conditions are the respective bodies.

Each equational Horn theory 8 generates a smallest congruence relation =s called 8-equality on the set of terms r(SUF) (the least equational theory which contains all logic consequences of 8 under the entailment relation |= obeying the axioms Eq5 of the equality for 8). 8 is a presentation or axio-matization of =£. In abuse of notation, we sometimes speak of the equational theory 8 to denote the theory axiomatized by 8. We will denote by H/8 the finest partition t(£)/ =£ induced by =£ over the set of ground terms t(£). H/8 is usually called the initial algebra of 8 [19], Satisfiability in %/8 is called 8-unifiability, that is, given a set of equations E, E is £-unifiable iff there

5 The set Eq of equality axioms for a given program 1Z are: reflexivity (x = x <i=), symmetry (x = y -4= y = x), transitivity (x = z <i= x = y, y = z) and f-substitutivity (f(xi,... ,xn) = f(yi,--.,y„) <=x1=y1,...,xn = yn, for f/n G S).

exists a substitution a such that £ |= Eo [19]. The substitution a is called an ^-unifier of E. Let =n be the reflexive, symmetric, and transitive closure of If £ is the set of (conditional) equations corresponding to 7Z, then

=s and =n coincide. Via this correspondence, the notion of ^-unification is implicitly defined. We say that 9 <r a [W] if there is a substitution 7 such that 97 =n a [W], i.e. x9j =n xa for all x G W.

2.1 Functional Logic Programming

Functional logic languages are extensions of functional languages with principles derived from logic programming [42]. The computation mechanism of functional logic languages is based on narrowing, a generalization of term rewriting where unification replaces matching: both the rewrite rule and the term to be rewritten can be instantiated. Under the narrowing mechanism, functional programs behave like logic programs: narrowing solves equations by computing solutions with respect to a given CTES, which is henceforth called the "program".

Definition 2.1 (Narrowing) Let 1Z be a program and g be an equational goal. We say that g conditionally narrows into g' if there exists a position u G 0(g), a standardized apart variant r = (A —p <= C) of a rewrite rule in 7Z, and a substitution a such that: a is the most general unifier of g\u and X,

f 0"J (J

and g' = (C, g[p]u)a. We write g g' or simply g g'. The relation is called (unrestricted or fullJ conditional narrowing.

0 * 6\

A narrowing derivation for g in 1Z is defined by g g' iff 30i,..., 39n. g

... g' and 9 = 9i... 9n. We say that the derivation has length n. If n = 0, then 9 = e. The extension of a CTES 7Z with the rewrite rules for dealing with the equality is denoted by 7Z+. In the case of unrestricted narrowing, 7Z+ denotes TZU {x = x ^ true}, x G V. This allows us to treat syntactical unification as a narrowing step, by using the rule (x = x —>■ true) to compute rngu's. Then s = t true holds iff a = mgu({s = i}).

We use the symbol T as a generic notation for sequences of the form true,... ,tru,e. A successful derivation (or refutation) for g in 7Z+ is a narrowing derivation g T, where 9\var(g) '1S the computed answer substitution (cas).

The narrowing mechanism is a powerful tool for constructing complete £-unification algorithms for useful classes of equational theories. In this context, completeness means that, for every solution to a given set of equations, a more general solution can be found by narrowing. Formally, a narrowing algorithm is complete for (a class of) CTES's if it generates a solution at least as general as any that satisfies the query (it generates a complete set of ^-unifiers).

2.2 Complete Narrowing Strategies

Since unrestricted narrowing has quite a large search space, several strategies to control the selection of redexes have been developed, A narrowing strategy (or position constraint) is any well-defined criterion which obtains a smaller search space by permitting narrowing to reduce only some chosen positions, A narrowing strategy <p can be formalized as a mapping that assigns a subset ip(g) of 0(g) to every goal g (different from T) such that, for all u E <p(g), the goal g is narrowable at position u. An important property of a narrowing strategy <p is completeness, meaning that the narrowing constrained by <p is still complete. There is an inherited tradeoff coming from functional programming, between the benefits of outside-in evaluation of orthogonal, nonterminating rules and those of inner or eager evaluation with terminating, non orthogonal rules, A survey of results about the completeness of narrowing strategies can be found in [4,21,22,29], To simplify our notation, we let II>r denote the class of CTRS's which satisfy the conditions for the completeness of the narrowing strategy (p.

We let inn(g) (resp, out(g)) denote the narrowing strategy which assigns the position p of the leftmost-innermost (resp, leftmost-outermost) narrowing redex of g to the goal g. 6 We formulate a conditional narrower with strategy <p, <p E {inn, out}, as the smallest relation satisfying

u = ip{g) A (A p 4= C) « A a = rngu({glu = A})


For Lp E {inn, out}, 7vr . =7lU {Eqv}, where Eqv are the rules which model the equality on data terms:

c =v c —true % c/0 E C

c(x 1, ...,xn)=ip c(yi,..., yn) —(x\ =tp ?/i) A ... A (xn =v yn) % c/n E C

Here =v is the standard equality = of terms whenever ¡p = inn, while for the case when ¡p is out, and nonterminating rules are considered, we need to distinguish the standard (non-strict) equality =, which is defined on partially determined or infinite data structures from the strict equality which is only defined on finite and completely determined data structures, and which gives to equality the weak meaning of identity of finite objects (e.g., see [39]), We also assume that equations in g and C have the form s = t whenever we consider <p = inn, whereas the equations have the form s pz t when we consider ip = out. Note that a non-strict equation like f(a) = g(a) is not an acceptable goal when ¡p = out.

6 An innermost term is an operation applied to constructor terms, i.e., a term of the form f(di,..., dk), where / € T and for all z = 1,... ,k, ck G t(C U V). The leftmost-innermost position of g is the leftmost position of g which points to an innermost subterm. A position p is leftmost-outermost in a set of positions O if there is no p' £ O with p' prefix of p, or p' = q.i.q' and p = q.j.q" and i < j.

Innermost narrowing is the foundation of several functional logic programming languages like SLOG [26], LPG [7,8] and (a subset of) ALF [28], Innermost narrowing corresponds to the eager evaluation strategies in functional programming. Modern functional logic languages like Curry [31], Escher [35] and Toy [13] are based on lazy evaluation principles, which delay the evaluation of function arguments until their values are needed to compute some result. This avoids unnecessary computations and allows one to deal with infinite data structures [29], Needed narrowing is a complete lazy narrowing strategy which is optimal w.r.t, the length of the derivations and the number of computed solutions in inductively sequential programs. Informally, inductive sequentially amounts to the existence of discriminating left-hand sides, i.e. typical functional programs. Needed narrowing can be easily and efficiently implemented by translating definitional trees into case expressions as proposed in [32], which also proves that there is a strong equivalence of needed narrowing derivations in the original program and leftmost-outermost narrowing derivations in the transformed program, A similar transformation is presented in [44], where inductively sequential programs are translated to uniform form, which has only flat rules with pairwise non-subunifiable left-hand sides, where the strong equivalence between needed narrowing and leftmost-outermost narrowing derivations also holds.

3 Denotation of a Functional Logic Program

A Herbrand interpretation I for a program 1Z is a set of ground equations, with the understanding that s = t is true w.r.t, I iff s = t E I. A Herbrand interpretation satisfies a program clause iff, for each ground instance A = p ■== (' of the clause, we have that A = p E I whenever C C I. A Herbrand ^-interpretation for 1Z is a Herbrand interpretation for 1Z obeying the equality axioms for 1Z. A Herbrand model for 1Z is a Herbrand interpretation for 1Z which satisfies each program clause in 1Z. A Herbrand i?-model for 1Z is a Herbrand model for 1Z which satisfies the equality axioms for 1Z. The intersection of all Herbrand E-models for 1Z is also a Herbrand i?-model for 1Z (the least Herbrand i?-model), and it was proposed as the declarative semantics for positive programs [33]. This semantics is known to be isomorphic to the initial algebra %/£ of the program, and in the following will be denoted by M{1Z).

For canonical programs, M{1Z) is equivalent to the operational semantics given by the ground success set, i.e. the set of all ground equations s = t such that s and t have a common 7?.-normal form, and to the fixpoint semantics given by the least fixpoint Tn-\uj of the following transformation Tn (immediate consequence operator), which is continuous on the complete lattice of

Herbrand interpretations ordered by set inclusion [33],

Tn{I) = {t = teB } L {< e B (X^p^C)E [1Z],

{e[p]u} U C C /, u e 0(e), e\u = A }

Informally, Tn(I) contains the set of all ground instances of the reflexivity axiom and the set of all ground equations that can be 'constructed' from elements of the Herbrand interpretation I by replacing one occurrence of the right-hand side of the head of a rule in 1Z by the corresponding left-hand side. In order to formulate a semantics for functional logic programs modeling computed answers, the usual Herbrand base has to be extended to the set of all (possibly) non-ground equations modulo variance [23,24], Hy denotes the V-Herbrand universe which allows variables in its elements, and is defined as r(E U V)/K. For the sake of simplicity, the elements of Hy have the same representation as the elements of r(E U V) and are also called terms. By denotes the V-Herbrand base, namely, the set of all equations s = t modulo variance, where s, t e Hy. Note that the standard Herbrand base B is equal to [By], The preorder < on r(EUF) induces an order relation on r(EUF)/~ (and therefore on Hy). The ordering on Hy induces an ordering on By, namely s' = t' < s = t if s' < s and t' < t. The power set of By is a complete lattice under set inclusion.

In the following, we introduce a semantics F^a(7Z) for program 1Z such that the computed answer substitutions of any (possibly conjunctive) goal g can be derived from Ffpa(7Z) by unification of the equations in the goal with the equations in the denotation. We assume that the equations in the denotation are renamed apart. Equations in the goal have to be flattened first, i.e. subterms have to be unnested so that the term structure is directly accessible to unification.

Definition 3.1 (flat goal w.r.t. cp) A flat equation is an equation of the form f(di,,,,, dn) = d or di =ip d2, where d, di,..., dn e r(C U V) are constructor terms. A flat goal is a set of flat equations.

For the outermost strategy, tp = out, the only non-strict equations in a flat goal are of the form f(d) = x. These equalities are treated differently from those originally present in the bodies of program rules and in the goal (denoted by «). In particular, the clauses for = must allow the elimination of f(a) = x, whenever f(a) would not have been selected by narrowing (i.e., when its value is not required to reduce g(f(a)).

Any sequence of equations E can be transformed into an equivalent one, flatv(E), which is flat. The flattening procedures for equation sets which produce flat goals w.r.t, inn and out, respectively, can be found in [10,27],

It is known that the fixpoint semantics allows for the reconstruction of the top down operational semantics and allows for the (bottom-up) computation of a model which is completely independent from the goal.

3.0.1 Fixpoint Semantics

Now we are ready to introduce a new, generic immediate consequence operator which models computed answers w.r.t, (p. For any program 7Z, we denote by $7j the set of identical equations f(xi,,,, ,xn) = f(xi,... ,xn), for each function symbol f/nEV. We let denote the set of the identical equations c(xi,,,,, xn) =,P c(xi,,,,, xn) for the constructor symbols c/n occurring in 7Z only. As we will see, these functional reflexivity axioms play an important role in defining the fixpoint semantics of 7Z.

In non-strict languages, if the compositional character of meaning has to be preserved in presence of infinite data structures and partial functions, then non-normalizable terms, which may occur as subterms within normali-zable expressions, also have to be assigned a denotation. Such a denotation is bound to the class of all partial results of the infinite computation along with the usual approximation ordering on them [27,39] or, equivalentlv, the infinite data structure defined as the least upper bound of this class. Following [27,39], we introduce a fresh constant symbol ± into £ to represent the value of expressions which would otherwise be undefined.

Definition 3.2 Let I be a Herbrand interpretation and 1Z E ll>r. Then, 'iyR(T) = $R U U {e e Bv | (A ^ p 4= C) « 1Ztp,

{l = r}UC' C X, mgu(flatv(C),C) = a, mgu({A = r|M}o") = 0, u E Olp(r), e = (l = r[p]u)aO }. where 7Z'p = 7Z if <p = inn, while 7Z'p = 7ZU {f(t) —-L | f/nE T>} if <p = out. The following proposition allows us to define the fixpoint semantics.

Proposition 3.3 The T^ operator is continuous on the complete lattice of Herbrand interpretations, <p E {inn, out}. The least fixpoint lfp(T%) = T^fw.

Definition 3.4 The least fixpoint semantics of a program 7Z in M,P is defined as Ttp(TZ) = lfp(T£), <p E {inn, out}.

Definition 3.5 We let F^a(7Z) denote {I = r E lfp(T%) \ r does not contain any defined function symbol f/n E V}, ip E {inn, out}.

Theorem 3.6 (strong soundness and strong completeness)

Let TZ be a program in M,P and g be a (non-trivial) goal according to ¡p. Then 0 is an answer substitution computed by -^tp for g in 7Z iff there exist g' = (ei,..., en) « F"P{TZ) such that 0 = mgu(flattp(g), g') \var(9)-

Example 3.7 Let us consider the program 7Z = (g(x) —0, f(0) —0, f(s(x)) —f (x)}. According to Definition 3-4, T^n{TZ) = {0 = 0, s(x) = s(x), g(x) = 0, f (0) = 0, f (s(0)) = 0,..., f (sn(0)) = 0,...}. Given the goal g = (y = f(z)), innermost narrowing computes the answers {{y/0,z/0}, {y/0, z/s(0)},

,,,, {y/0, z/sn(0)},,,,} in 7Z, which exactly coincides with the set of substitutions computed by unifying the flat goal f (z) = у with the equations in J~inn (•

Example 3.8 Now consider the program 1Z = {from(x) —[x|from(s(x))], first([x|y]) —x}. According to Definition 3-4, = (s(x) « s(x),

from(x) = ±, from(x) = [x|±],..., from(x) = [x|[s(x)| ... [s»(x)|±]]],..., first(x) = ±, first([x|y]) = x}, with n E из. Given the goal g = (first (from(s(x))) « z), outermost narrowing only computes the answer {z/s(x)} in 7Z, which is also the only substitution which can be computed by unifying the flat goal ff irst(y) = w, from(s(x)) = y, w « z) in Т™л(1Z).

According to Theorem 3,6, F^a(7Z) can be used to simulate the execution for any (non-trivial) goal g, that is, F^a(7Z) can be viewed as a (possibly infinite) set of 'unit' clauses, and the computed answer substitutions for g in 1Z can be determined by 'executing' flat(g) in the program Ffpa(7Z) by standard unification, as if the equality symbol were an ordinary predicate. In the following, we show the relation between the semantics F^a(7Z) and a novel operational "computed answer" semantics 0™(1Z) which correctly models the behavior of single equations, which we introduce in the following,

3.0.2 Computed Answer Semantics

The operational success set semantics 0™(1Z) of a program 1Z w.r.t, narrowing semantics is defined by considering the answers computed for "most general calls", as shown by the following definition.

Definition 3.9 Let 1Z be a program in H\ r. Then,

0™{П) = ^ U {(/(aib ...,xn)= xn+i)0 I (f(xi, ...,xn)=ip xn+i) T where f /n EV, xn+i and ац are distinct variables, for i = 1,... ,n}.

The equivalence between the operational and the least fixpoint semantics is established by the following theorem.

Theorem 3.10 IflZE Rinn, then O^JTZ) = Р£п{П).

If 1Z E Rout, then 0™t(lZ) = {I = r E 1Z) \ ± does not occur in r}

The following theorem relates the non-ground semantics 0™(1Z) to the standard least Herbrand i?-model semantics M{1Z).

Theorem 3.11 Let TZ be a program in IIir and rT be the transitive-symmetric closure of relation r under replacement (the /-substitutivitv property). Then,

M{iz) = [o?(K)F.

4 Diagnosis of declarative programs

We now introduce some basic definitions on the diagnosis of declarative programs [17]. As operational semantics we consider the set of computed answer


Definition 4.1 Let X be the specification of the intended computed answer semantics for 7Z.

(i) 7Z is partially correct w.r.t. X, if 0™(7Z) C X.

(ii) 7Z is complete w.r.t. X, ifXC Ofp(7Z).

(iii) 7Z is totally correct w.r.t. X, if 0^(7Z) =X.

If a program contains errors, these are signalled by corresponding symptoms.

Definition 4.2 Let X be the specification of the intended computed answer semantics for 1Z.

(i) An incorrectness symptom is an equation e such that e e 0™(7Z) and e^X.

(ii) An incompleteness symptom is an equation e such that eel and e 0 o™(TZ).

In case of errors, in order to determine the faulty rules, we give the following definitions.

Definition 4.3 Let X be the specification of the intended fixpoint semantics for 1Z. If there exists an equation e e Tj^(Z) and e 0 X , then the rule r ETZ is incorrect on e.

Therefore, the incorrectness of rule r is signalled by a simple transformation of the intended semantics X.

Definition 4.4 Let X be the specification of the intended fixpoint semantics for 1Z. An equation e is uncovered if e e X and e 0 T^(X).

By the above definition, an equation e is uncovered if it cannot be derived by any program rule using the intended fixpoint semantics.

Proposition 4.5 If there are no incorrect rules in 7Z w.r.t the specification of the intended fixpoint semantics, then 7Z is partially correct w.r.t. the intended computed answer semantics.

We now consider a bottom-up abstract debugger for a strict language. Hence, in the rest of this paper, we fix ¡p = inn.

5 Abstract success set

The theory of abstract interpretation [18] provides a formal framework for developing advanced data-flow analysis tools. Abstract interpretation formalizes the idea of 'approximate computation' in which computation is performed with descriptions of data rather than with the data itself. The semantics operators are then replaced by abstract operators which are shown to 'safely' approximate the standard ones. In this section, starting from the fixpoint semantics

in Section 3, we develop an abstract semantics which approximates the observable behavior of the program and is adequate for modular data-flow analysis, such as the analysis of unsatisfiabilitv of equation sets or any analysis which is based on the program success set. We assume the framework of abstract interpretation for analysis of equational unsatisfiabilitv as defined in [2], Another approach to constructing an abstract term rewriting system is followed in [9], We think that another approximation of the fixpoint semantics given in the previous section which is different from the one that we describe in this section can be characterized by following an approach similar to that in [9]. We first recall the abstract domains and the associated abstract operators. Then we describe a novel abstract immediate consequence operator T^ which is able to approximate the operator Tn, and the abstract fixpoint semantics In the following, we denote the abstract analog of a concrete object O by OK

5.1 Abstract Domains and Operators

A description is the association of an abstract domain (£>, <) (a poset) with a concrete domain (E, <) (a poset). When E = Eqn or E = Sub, the description is called an equation description or a substitution description, respectively. The correspondence between the abstract and concrete domain is established through a 'concretization' function 7 : D —2E. We say that d approximates e, written d oc e, iff e E 7(d). The approximation relation can be lifted to relations and cross products as usual [2].

Abstract substitutions are introduced for the purpose of describing the computed answer substitutions for a given goal. Abstract equations and abstract substitutions correspond, in our approach, to abstract program denotations and abstract observable properties, respectively. The domains for equations and substitutions are as follows.

Definition 5.1 (abstract Herbrand universe) Let jj be an irreducible symbol, where jj 0 E. Let Hy = (r(E U V U {J}), be the domain of terms over the signature augmented by jj, where the partial order < is defined as follows:

(a) Vi E Hy.jj t and t <t and

(b) Vsi,..., sn, s[, ...,s'n E %y.yf/n E E. si ± si A ... A s'n ± sn => /(si,...,<) ^ /(si,...,s„).

This order can be extended to equations: s' = t' < s = t iff s' s and t' -<t and to sets of equations S, S':

1) S' ^ S iff We' E S'3e E S such that e' ^ e. Note that S' ^ {true} S' = {true}.

2) S'QS iff (S' 3 S) and (S ^ S' implies S' C S).

Intuitively, S' Q S means that either S' contains less information than S, or if they have the same information, then S' expresses it using fewer elements,

Roughly speaking, the special symbol jj introduced in the abstract domains represents any concrete term. The behaviour of the symbol jj from a programming viewpoint resembles that of an "anonymous" variable in Prolog, From the viewpoint of logic, jj stands for an existentiallv quantified variable [2,37,38], Define [Sj = S', where the n-tuple of occurrences of jj in S is replaced by an n-tuple of existentiallv quantified fresh variables in S'.

Definition 5.2 An abstract substitution is a set of the form {xi/ti,..., xn/tn} where, for each i = 1,... ,n, Xi is a distinct variable in V not occurring in any of the terms ti,... ,tn and ti E r(E U V U {jj}). The ordering on abstract substitutions is given by logical implication: let 9,k E Su$, k < 9 iff ¡0} =► [«].

The descriptions for terms, substitutions and equations are as follows.

Definition 5.3 Let Uv = (r(E U V),<) and U\ = (r(E U V U {jj}),^). The term description is {Hy,j,Hv) where j : Hy —2Hv is defined by: y(t>) = {tE Hv\t' 1 t}.

Let Eqn be the set of finite sets of equations over r (E U V) and Eqnbe the set of finite sets of equations over r(E U V U {jj}). The equation description is ((EqnP, C),7, (Eqn, <)), where 7 : Eqn" —2Eqn is defined by: 7(g') = {g E Eqn\g' C g and g is unquantified }.

Let Sub be the set of substitutions over r(E U V) and Sub" be the set of substitutions over r(E U V U {jj}). The substitution description ((Sub^, ),7, (Sub, <)), where 7 : Su$ 2Sub is defined by: 7(k) = {9 E Sub\K 9}.

In order to perform computations over the abstract domains, we have to define the notion of abstract unification. The abstract most general unifier for our method is very simple and, roughly speaking, it boils down to computing a solved form of an equation set with (possibly) existentiallv quantified variables. We define the abstract most general unifier for an equation set S' E Eqnas follows. First replace all occurrences of jj in S' by existentiallv quantified fresh variables. Then take a solved form of the resulting quantified equation set and finally replace the existentiallv quantified variables again by jj. Formally: let 3yi... yn.S = solve(lS'J) and k = {yi/jj,..., yn/\!}■ Then rngiJ'(S') = Sk . The fact that W E unifdS}). mgu^(S) < 9 justifies our use of'most general'. The safety of the abstract unification algorithm has been proven in [2],

Our analysis is based on a form of simplified (abstract) program which always terminates and in which the query can be executed efficiently. Our notion of abstract program is parametric with respect to a loop-check. Two different instances can be found in [2,3],

Definition 5.4 A loop-check is a graph Qn associated with a program 7Z, i.e. a relation consisting of a set of pairs of terms, such that:

(1) the transitive closure C/.R is decidable and

(2) Let t = t' be a function which assigns to a term t some node t' in Qn-If there is an infinite sequence:

(<= G0,90) (<= Gi, 0i) .

then 3i > 0. (ti,ti) G Gk.- where t{ — e\c G G, and u G 0(e). (we refer

to (ti,ti) as a 'cycle' ofQn-)

A program is abstracted by simplifying the right-hand side and the body of each clause. This definition is given inductively on the structure of terms and equations. The main idea is that terms whose corresponding nodes in gn have a cycle are drastically simplified by replacing them by jj, We use this definition in a iterative manner. We first abstract a concrete rule r obtaining rtt (we select a rule with direct recursion if any; otherwise we choose any rule in the program). Then we replace r by in 7Z, and recompute the loop-check before proceeding to abstract the next rule. Each concrete rule is considered only once in the abstraction process.

Definition 5.5 (abstract rule) Let 1Z be a program and let r = (A —p 4=

C) e 7Z. Let Q-ji be a loop-check for 7Z. We define the abstraction of r as follows: H = (A —sh{p, Qn) <= sh{C, On)) where the shell sh{x, Q) of an expression x according to a loop-check Q is defined inductively

x if x e V

f{sh{ti,g),.. .,sh{tk,g)) ifx = f{ti, ...,tk) and (x,x) £ Q sh(x, g) = sh(i, g) = sh(r, g) %fx = {i = r)

sh(ei,g),.. ,,sh(en,g) if x = e i,...,en jj otherwise

We can now formalize the abstract semantics.

5.2 Bottom-up Abstract Semantics

We define an abstract fixpoint semantics in terms of the least fixpoint of a continuous transformation T^ based on abstract unification and the operation of abstraction of a program. The idea is to provide a finitely computable approximation of the concrete denotation of the program 1Z. In the following, we define the abstract transformation T^.

Definition 5.6 (abstract Herbrand base, abstract Herbrand interpretation) The abstract Herbrand base of equations B{ is defined as the set of equations over the abstract Herbrand universe Hy. An abstract Herbrand interpretation is any element of 2s*'. A 'partial order C^ on abstract interpretations can be defined in a way similar to the order C on interpretations.

We can show that the set of abstract interpretations is a complete lattice w.r.t, cK An abstract trivial equation is an equation jj = X, X = jj or jj = jj.

Definition 5.7 Let 1Z be a program, gn be a loop-check for 1Z and V) be the abstraction of 7Z using g-ji where we also drop any abstract trivial equation

from the body of the rules. Let I be an abstract interpretation. Then, 1^(1) = $K U U {e G B{, | (A p 4= C) « 1ZK,

{l = r}UC' C 1, mguHflat(C),C) = a, rngiJ({X = (rlu)}a) = e, u E 0(r), e = (I = r[p]u)o9 }.

Proposition 5.8 The T^ operator is continuous on the complete lattice of abstract interpretations.

We can define 2^(1Z) and 2:ca^{TZ) in a way similar to the concrete constructions of 2:ip{7Z) and as in Section 3,

Definition 5.9 (abstract least fixpoint semantics) The abstract least fixpoint semantics of a program 7Z is 2-^(7Z) = lfp(T^). Let 2-ca^(7Z) = {I = r E 2^(1Z) | r does not contain any defined function symbol f/nE T>}

The following theorem states that 2^(1Z) and Fca^(7Z) are finitely computable.

Theorem 5.10 There exists a finite positive number k such that 2^(1Z) =

From a semantics viewpoint, given a program 7Z, the fixpoint semantics 2:{1Z) (resp, 2:ca{7Z)) is approximated by the corresponding abstract fixpoint semantics 2^(1Z) (resp, 2:ca^{TZ)). That is, we can compute an abstract approximation of the concrete semantics in a finite number of steps. The correctness of the abstract fixpoint semantics with respect to the concrete semantics is proved by the following:

Theorem 5.11 There exists a finite positive number k such that i"R f k x Tntoo.

Corollary 5.12 P{1Z) oc F{1Z) and fcai(TZ) oc Fca{1Z).

The semantics 2:ca^{TZ) collects goal-independent information about success patterns of a given program. The relation between the abstract fixpoint and the concrete operational semantics (computed answer substitutions) is given by the following theorem. Roughly speaking, given a goal 4= G, we obtain a description of the set of the computed answers of 4= G by abstract unification of the equations in flat(G) with equations in the approximated semantics 2:ca^{TZ).

Theorem 5.13 (strong completeness) Let 1Z be a program in II>r and

<= g be a non-trivial goal. If 9 is a computed answer substitution for <= g in 7Z, then there exists g' = e i,,,, ,eTO C 2-ca^(7Z) such that 9' = mgvP(flat(g), g') and 9' ^ 9.

Example 5.14 Let us consider the program 1Z = (g(0) —0, g(c(x)) —

Semantic Property Requirement

1Z is partially correct w.r.t. jBe.e €E Tn{T~) and e

1Z is complete w.r.t. jBe.e €E and e 0 T-ji(l+)

1Z is incorrect w.r.t. 3e.e €E Tn(I~) and e

1Z is incomplete w.r.t. 3e.e €E 1and e 0 T-ji(l+)

Table 1

Sufficient Conditions for Correctness and Completeness c(g(x)), f (0) —0, f (c(x)) —x 4= g(c(x)) = c(x)}. Let us consider the loop-

check [3] Qiz = {(g(x),g(x))}, and let t= t' be the ('partial) function which, given a graph, assigns to a term t some node t' in the graph such that t' unifies with t, if one such node t' exists.

Then, the abstraction of the program 7Z is TZ* = (g(0) ^ 0, g(c(x)) ^ c(jj), f (0) ^ 0, f (c(x)) ^ x 4= g(c(x)) = c(x)}.

Z) = {0 = 0, g(x) = g(x), f (x) = f (x), c(x) = c(x), g(0) = 0, f (0) = 0, g(c(x)) = c(g(x)),..., g(c»(x)) = c»(g(x)),..., g(c(0)) = c(0),,,,, g(cn(0)) = cn(0),... ,f(c(0)) = 0,..., f(cn(0)) = cn_1(0),...} and the corresponding fixpoint abstract semantics is the finite set

P(1Z) = {0 = 0, g(x) = g(x), f (x) = f (x), c(x) = c(x), g(0) = 0, f (0) = °> g(c(x)) = c(tt), f(c(x)) = x}, and

1Z) = {0 = 0, c(x) = c(x), g(0) = 0, f(0) = 0, g(c(x)) = c(jj), f(c(x)) = x} which approximates the program success set.

Given a goal <= g = <= f (g(x)) = y, innermost conditional narrowing computes the infinite set of substitutions {{x/0, y/0}, {x/c(0), y/0}, {x/c2(0), y/c(0)},,,,, {x/cn(0), y/cn-1(0)}}. The abstract substitutions returned by abstract unification of the equations in the flattened goal 4= f (z) = y, g(x) = z with Z) are {{x/0, y/0}, {x/c(x'),y/jj}}, which approximate the computed answers of <= g.

6 Abstract diagnosis

An efficient debugger can be based on the notion of over-approximation and under-approximation for the intended fixpoint semantics that we have introduced, The basic idea is to consider two sets to verify partial correctness: X+ which overapproximates the intended semantics X (that is, X C 7(X+)) and X- which underapproximates X (that is, X D 7(X-)), We can then use such sets as shown in Table 1,

Proposition 6.1 If there exists an equation e such that e 0 X+ and e e T{rj(I^), then the rule r ETZ is incorrect on e.

Proposition 6.2 If there exists an equation e such that e 0 Tn(I+) and (El. then the equation e is uncovered.

In the following, by abuse we let X denote the program that specifies the intended semantics. In the following, we consider X+ = lfp(Tj), i.e. we consider the abstract success set that we have defined in previous section as overapproximation of the success set of a program. We can consider any of the sets defined in the works of [11,16] as underapproximation of X, Alternatively, we can simply take the set which results from a finite number of iterations of the Tj function (the concrete operator). Let us illustrate this method.

Example 6.3 Let us consider a program 1Z = (g(0) —0, f (0) —0, g(c(x))

—g(x), f (c(x)) —x 4= g(c(x)) = c(x)} which is incorrect when we consider

as intended specification the following program

X = (g(0) 0, f (0) 0, g(c(x)) c(g(x)), f (c(x)) g(x)}.

Then, by using the loop check in Example 5.14 we have

X« = (g(0) 0, f (0) 0, g(c(x)) c(jj), f (c(x)) g(x)}.

After three iterations of the Tj operator, we get:

1- = {0 = 0, c(x) = c(x), f(x) = f(x), g(x) = g(x), f(0) = 0, g(0) = 0, f(c(x)) = g(x), g(c(x)) = c(g(x)), f(c(0)) = 0, g(c(0)) = c(0), f(c2(x)) = c(g(x)), g(c2(x)) = c2(g(x)), f(c2(0)) = c(0),f(c3(x)) = c2(g(x)), g(c2(0)) = c2(0), g(c3(x)) = c3(g(x))}.

After two iterations of the T| operator, we get the fixpoint: X+ = r-CI) = lfp(Tl) = {0 = 0, c(x) = c(x), f(x) = fix). g(x) = g(x), f(0) = 0, g(0) = 0, f(c(x)) = g(x), g(c(x)) = c(jj), f(c(0)) = 0, f(c2(x)) = c(jj)}. And

Tn(l-) = {0 = 0, c(x) = c(x), f(x) = f(x), g(x) = g(x), f(0) = 0, g(0) = 0, g(c(x)) = g(x), f(c(0)) = 0, f(c2(x)) = g(x), g(c(0)) = c(0), g(c2(x)) = c(g(x)), f(c2(0)) = c(0), f(c3(x)) = c(g(x)), g(c2(0)) = c2(0), f(c3(0)) = c2(0),f(c4(x)) = c2(g(x)), g(c3(x)) = c2(g(x)), g(c3(0)) = c3(0), g(c4(x)) = c3(g(x))}.

Now we can derive that g(c(x)) = g(x) £ %while g(c(x)) = g(x) 0 X+. Hence, the corresponding rule g(c(x)) —g(x) is wrong.

7 The System for Declarative Debugging buggy

The basic rules presented so far have been implemented by a prototype system Buggy [1], which is available at

It includes a parser for a conditional functional logic language, whose semantics is based on innermost (basic) narrowing, which is a generalization of basic narrowing such that 1Z does not need to be completely defined, which is quite a restrictive condition which is necessary for the completeness of innermost narrowing [10,33]. The implementation also includes a module for computing an abstraction of the program based on a given loop-check, an automatic debugger which requires that the user indicate some parameters, such as the number n of iterations for approximating the success set from the bottom.

Then the errors are automatically found by the debugger and the user has to indicate the corrections to be made on the wrong rules. The Buggy system is written in SICStus Prolog v3.8.1 and the complete implementation consists of about 300 clauses (1260 lines of code). The debugger is expressed by 147 clauses (including the user interface and the code needed to handle the representation), the parser and other utilities are expressed by 65 clauses and basic narrowing is implemented by 88 clauses. Language syntax follows mainly that of a generic conditional functional logic language, with conditional basic narrowing.

The Buggy main screen allows the user to choose between several alternatives,

(i) File options: It contains the classical options for opening, loading and saving a file, as well as cleaning and exiting the system,

(ii) Edit: it is possible to load, edit, and visualize the program to be debugged on the screen, as well as its intended semantics. The program is incrementally parsed while it is loaded,

(iii) Debug: the debugger starts debugging the input program w.r.t, the intended semantics. The user has to say how many iterations to apply for approximating from below the intended semantics. The errors are shown one by one to the user who is required to propose the corrections which are in turn tested. The final correct program is shown to the user who can save it,

(iv) Help: contains additional information about the system.

We have tested our debugging methodology over several benchmarks. We have considered programs such as append for computing the concatenation of two input lists, last which returns the last element of a list, knapsack which returns a set of elements of the input list whose weight sum is equal to an input integer value, f ibonacci which computes the Fibonacci numbers, fact which computes the factorial of a positive number, sort which uses the insertion sort for ordering an input list of integers. For all these programs by using the intended semantics we detected the errors which were inserted in the program. The final programs passed the tests of correctness and completeness.

Let us illustrate the power of our debugging system when functional logic programs are used as specification of the intended semantics. The idea goes back to the origins of declarative programming, considering declarative specifications as programs for rapid prototyping [15]. In our case, we go one step further, because the intended specification can then be automatically abstracted and can be used to automatically debug the final efficient program.

The following program should order a list of integers using the insertion sort,

sort([X]) ^ []. sort (X XsJ ->• Ys 4= sort(Xs) = Zs,

insert(X. Zs. Ys) = true,

insert(X, [], [X]) —true,

insert(X. [Y|Ys], [Y|Zs]) ->• true ^ X > Y = true,

insert(X, Ys, Zs) = true,

insert(X, [Y|Ys], [X,Y|Ys]) ->• true <= X =< Y = true.

The intended specification X is given by the (quite) inefficient program which uses the naive sorting algorithm which computes the permutations of the input list,

sort(Xs) —Ys 4= perm(Xs) = Ys, ord(Ys) = true, ord([]) —true, ord([X]) ->• true, ord( X. Y XsJ ->• true <= X =< Y = true, ordfY XsJ = true. perm(Xs) —[Z|Zs] 4= select(Z,Xs,Ys) = true,

perm(Ys) = Zs,

perm([]) —[].

select(X, [X|Xs],Xs) ->• true,

select(X, [Y|Xs], [Y|Zs]) ->• true 4= select(X, Xs, Zs) = true.

The overapproximation X+ is given by the following set of equations: {sort([A | B]) = [jj], sort([]) = [], select(X,[Y|Z],[Y|jj]) = true, select(X,[X|Y],Y) = true, perm([]) = [], perm([X | Y]) = [jj|jj], ord([X]) = true, ordQ = true, select(X, Y, Z) = select(X, Y, Z), X =< Y = X =< Y, [X|Y] = [X|Y], [] = [], ord(X) = ord(X), true = true, perm(X) = perm(X), sort(X) = sort(X)}

Now the system detects that the program rule sort([X]) —[] is wrong. If the programmer replaces it with the correct equation sort([X]) —[X], the program becomes correct and complete according to our conditions,

8 Conclusions

We have presented an approach to declarative debugging of functional logic programs w.r.t, the set of computed answers. We have defined a declarative debugging method which has similarities to others which have been proposed

in the literature (such as [11,16]), but which is original w.r.t, the definition and use of the semantic equations for making the error diagnosis and is useful for both eager as well as for lazy languages. We have presented a novel fixpoint semantics for functional logic programs, which is parametric w.r.t, the narrowing strategy. This semantics characterizes the set of computed answers in a bottom-up manner. Thus, it is a suitable basis for dataflow analysis based on abstract interpretation. We present one example of abstraction of this fixpoint semantics which yields an approximated finite (goal-independent) description of the success patterns of the program and which can then be used in combination with our debugging equations to obtain an efficient and terminating debugging system. In this paper, we have discussed the successful experiments which have been performed with a prototypical implementation of our debugging system which is publicly available. We believe that it is possible to extend our system in several ways; for instance, by integrating other dataflow analysis for approximating term rewriting systems [9]. Another extension can be done by studying the relation and integration with assertion based methods for declarative debugging [20].


[1] M. Alpuente, F. J. Correa, M. Falaschi, and S. Marson. The Debugging System buggy. Technical report, UPV, 2001. Available at URL:

[2] M. Alpuente, M. Falaschi, and F. Manzo. Analyses of Unsatisfiability for Equational Logic Programming. Journal of Logic Programming, 22(3):221-252, 1995.

[3] M. Alpuente, M. Falaschi, and G. Vidal. A Compositional Semantic Basis for the Analysis of Equational Horn Programs. Theoretical Computer Science, 165(1):97—131, 1996.

[4] S. Antoy, R. Echahed, and M. Hanus. A needed narrowing strategy. Journal of the ACM, 47(4):776-822, 2000.

[5] P. Arenas and A. Gil. A debugging model for lazy functional languages. Technical Report DIA 94/6, Universidad Complutense de Madrid, April 1994.

[6] F. Baader and T. Nipkow. Term Rewriting and All That. Cambridge University Press, 1998.

[7] D. Bert and R. Echahed. Design and implementation of a generic, logic and functional programming language. In Proc. of First European Symp. on Programming, ESOP'86, pages 119-132. Springer LNCS 213, 1986.

[8] D. Bert and R. Echahed. On the Operational Semantics of the Algebraic and Logic Programming Language LPG. In Recent Trends in Data Type Specifications, pages 132-152. Springer LNCS 906, 1995.

[9] D. Bert, R. Echahed, and B.M. 0stvold. Abstract Rewriting. In Proc. of Third Int'l Workshop on Static Analysis, WSA'93, pages 178-192. Springer LNCS 724, 1993.

[10] P. Bosco, E. Giovannetti, and C. Moiso. Narrowing vs. SLD-resolution. Theoretical Computer Science, 59:3-23, 1988.

[11] F. Bueno, P. Deransart, W. Drabent, G. Ferrand, M Hermenegildo, J. Maluszynski, and G. Puebla. On the role of semantic approximations in validation and diagnosis of constraint logic programs. In Proc. of the 3rd. Int'l Workshop on Automated Debugging-AADFBUG'97', pages 155-170. U. of Linkoping Press, 1997.

[12] R. Caballero-Roldán, F.J. López-Fraguas, and M. Rodriquez Artalejo. Theoretical Foundations for the Declarative Debugging of Lazy Functional Logic Programs. In Fifth International Symposium on Functional and logic Programming, Lecture Notes in Computer Science. Springer-Verlag, Berlin, 2001. To appear.

[13] R. Caballero-Roldán, F.J. López-Fraguas, and J. Sánchez-Hernández. User's manual for Toy. Technical Report SIP-5797, UCM, Madrid (Spain), 1997.

[14] M. Codish, M. Falaschi, and K. Marriott. Suspension Analysis for Concurrent Logic Programs. In K. Furukawa, editor, Proc. of Eighth Int'l Conf. on logic Programming, pages 331-345. The MIT Press, Cambridge, MA, 1991.

[15] M. Comini, R. Gori, and G. Levi. Logic programs as specifications in the inductive verification of logic programs. In Proceeding of Appia-Gulp-Prode'00, Joint Conference on Declarative Programming, 2000. URL:

[16] M. Comini, G. Levi, M. C. Meo, and G. Vitiello. Abstract diagnosis. Journal of logic Programming, 39(l-3):43-93, 1999.

[17] M. Comini, G. Levi, and G. Vitiello. Declarative Diagnosis Revisited. In John W. Lloyd, editor, Proceedings of the 1995 Int'l Symposium on logic Programming, pages 275-287. The MIT Press, 1995.

[18] P. Cousot and R. Cousot. Abstract Interpretation: A Unified Lattice Model for Static Analysis of Programs by Construction or Approximation of Fixpoints. In Proc. of Fourth ACM Symp. on Principles of Programming languages, pages 238-252, 1977.

[19] N. Dershowitz and J.-P. Jouannaud. Rewrite Systems. In J. van Leeuwen, editor, Handbook of Theoretical Computer Science, volume B: Formal Models and Semantics, pages 243-320. Elsevier, Amsterdam, 1990.

[20] W. Drabent, S. Nadjim-Tehrani, and J. Maluszynski. The use of assertions in algorithmic debugging. In Proceedings of the 1988 Iinternational Conference on Fifth Generation Computer Systems, pages 573-581, Tokyo, Japan, December 1988.

[21] R. Echahed. On completeness of narrowing strategies. In Proc. of CAAP'88, pages 89-101. Springer LNCS 299, 1988.

[22] R. Echahed. Uniform narrowing strategies. In Proc. of 1С ALP'92, pages 259275. Springer LNCS 632, 1992.

[23] M. Falaschi, G. Levi, M. Martelli, and C. Palamidessi. Declarative Modeling of the Operational Behavior of Logic Languages. Theoretical Computer Science, 69(3):289-318, 1989.

[24] M. Falaschi, G. Levi, M. Martelli, and C. Palamidessi. A Model-Theoretic Reconstruction of the Operational Semantics of Logic Programs. Information and Computation, 103(1):86—113, 1993.

[25] G. Ferrand. Error Diagnosis in Logic Programming, and Adaptation of E.Y.Shapiro's Method. Journal of Logic Programming, 4(3):177-198, 1987.

[26] L. Fribourg. SLOG: a logic programming language interpreter based on clausal superposition and rewriting. In Proc. of Second IEEE Int'l Symp. on Logic Programming, pages 172-185. IEEE, New York, 1985.

[27] E. Giovannetti, G. Levi, C. Moiso, and C. Palamidessi. Kernel Leaf: A Logic plus Functional Language. Journal of Computer and System Sciences, 42:363377, 1991.

[28] M. Hanus. Compiling Logic Programs with Equality. In Proc. of 2nd Int'l Workshop on Programming Language Implementation and Logic Programming, pages 387-401. Springer LNCS 456, 1990.

[29] M. Hanus. The Integration of Functions into Logic Programming: From Theory to Practice. Journal of Logic Programming, 19&20:583-628, 1994.

[30] M. Hanus and B. Josephs. A debugging model for functional logic programs. In M. Bruynooghe and J. Penjam, editors, Proc. of 5th Int'l Symp. on Programming Language Implementation and Logic Programming, volume 714 of Lecture Notes in Computer Science, pages 28-43. Springer, 1993.

[31] M. Hanus, H. Kuchen, and J.J. Moreno-Navarro. Curry: A Truly Functional Logic Language. In Proc. ILPS'95 Workshop on Visions for the Future of Logic Programming, pages 95-107, 1995.

[32] M. Hanus and C. Prehofer. Higher-Order Narrowing with Definitional Trees. In Proc. Seventh Int'l Conf. on Rewriting Techniques and Applications, RTA'96, pages 138-152. Springer LNCS 1103, 1996.

[33] S. Holldobler. Foundations of Equational Logic Programming. Springer LNAI 353, 1989.

[34] J.W. Klop. Term Rewriting Systems. In S. Abramsky, D. Gabbay, and T. Maibaum, editors, Handbook of Logic in Computer Science, volume I, pages 1-112. Oxford University Press, 1992.

[35] J. W. Lloyd. Programming in an integrated functional and logic language. Journal of Functional and Logic Programming, 3, 1999.

[36] J.W. Lloyd. Declarative Programming in Escher. Technical Report CSTR-95-013, Computer Science Department, University of Bristol, 1995.

[37] M.J. Maher. Complete Axiomatizations of the Algebras of Finite, Rational and Infinite Trees. In Proc. of Third IEEE Symp. on Logic In Computer Science, pages 348-357. Computer Science Press, New York, 1988.

[38] M.J. Maher. On Parameterized Substitutions. Technical Report RC 16042, IBM - T.J. Watson Research Center, Yorktown Heights, NY, 1990.

[39] J.J. Moreno-Navarro and M. Rodriguez-Artalejo. Logic Programming with Functions and Predicates: The language Babel. Journal of Logic Programming, 12(3):191—224, 1992.

[40] L. Naish and T. Barbour. Towards a portable lazy functional declarative debugger. Australian Computer Science Communications, 18(l):401-408, 1996.

[41] Lee Naish. A declarative debugging scheme. Journal of Functional and Logic Programming, 1997(3), April 1997.

[42] U.S. Reddy. Narrowing as the Operational Semantics of Functional Languages. In Proc. of Second IEEE Int'l Symp. on Logic Programming, pages 138-151. IEEE, New York, 1985.

[43] E. Y. Shaphiro. Algorithmic Program Debugging. The MIT Press, Cambridge, Massachusetts, 1982. ACM Distinguished Dissertation.

[44] F. Zartmann. Denotational Abstract Interpretation of Functional Logic Programs. In P. Van Hentenryck, editor, Proc. of the 4th Int'l Static Analysis Symposium, SAS'97, pages 141-159. Springer LNCS 1302, 1997.