Fig. 1. Building ladders in T OY

In this example (see Fig. 1), T OY is used to implement the instance *CFLP*(R) of the *CFLP*(D) scheme, with the parameter D replaced by the real numbers domain R, which provides real numbers, arithmetic operations and various arithmetic constraints, including equalities, disequalities and inequalities. The type figure is intended to represent geometric figures as boolean functions, the function rect is intended to represent rectangles (more precisely, (rect (X,Y) LX LY) is intended to represent a rectangle with leftmost-bottom vertex (X,Y) and rightmost-upper vertex (X+LX,Y+LY)); and the function ladder is intended to build an infinite list of rectangles in the shape of a ladder. Although the text of the program seems to include no constraints, it uses arithmetic and comparison operators that give rise to constraint solving in execution time. More precisely, consider the following session in T OY:

**Example 2. (Debugging Missing Answers in** T OY**)**

of Wrong and Missing Answers in Declarative Constraint Programming

the program defined functions as possibly non-deterministic.

fDiff (X:Y:Zs) --> X // fDiff (Y:Zs) <== X /= Y fDiff (X:Y:Zs) --> X <== X == Y

gen :: A -> A -> [A] even :: int -> bool

could be mended by placing again the third rule for fDiff within the program.

In this section we summarize the essentials of the *CFLP*(D) scheme (López et al., 2006) for lazy Constraint Functional-Logic Programming over a parametrically given constraint domain D, which serves as a logical and semantic framework for the declarative diagnosis method

**3. The** *CFLP*(D) **programming scheme**

presented in the chapter.

(//) :: A -> A -> A

fDiff :: [A] -> A fDiff [X] --> X

X // \_ --> X \_ // Y --> Y

The following small *CFLP*(H)-program PfD, written in T OY syntax over the *Herbrand domain* H with equality (==) and disequality (/=) constraints, includes program rules for the non-deterministic functions (//) and fDiff, and the deterministic functions gen and even. Note the infix syntax used for (//), as well as the use of the equality symbol = instead of the rewrite arrow -> for the program rules of those functions viewed as deterministic by the user. This is just meant as user given information, not checked by the T OY system, which treats all

<sup>125</sup> A Semantic Framework for the Declarative Debugging

infixr 40 // % non-deterministic choice operator

gen X Y = X : Y : gen Y X even N = true <== (mod N 2) == 0

Function fDiff is intended to return any element belonging to the longest prefix Xs of the list given as parameter such that Xs does not include two identical elements in consecutive positions. In general, there will be several of such elements, and therefore fDiff is non-deterministic. Function gen is deterministic and returns a potentially infinite list of the form [*d*1, *d*2, *d*2, *d*1, *d*1, *d*2,...], where the elements *d*<sup>1</sup> and *d*<sup>2</sup> are the given parameters. Therefore, the lazy evaluation of (fDiff (gen 1 2)) is expected to yield the two possible results 1 and 2 in alternative computations, and the initial goal *G*fD : even (fDiff (gen 1 2)) == true for PfD is expected to succeed, since (fDiff (gen 1 2)) is expected to return the even number 2. However, if the third program rule for function fDiff were *missing* in program PfD, the expression (fDiff (gen 1 2)) would return only the numeric value 1, and therefore the goal *G*fD would fail unexpectedly. At this point, a diagnosis for *missing answers* could take place, looking for a *buggy node* in a suitable *CT* in order to detect some *incomplete* function definition (that of function fDiff, in this case) to be blamed for the missing answers. As we will see in Sections 6 and 7, this particular *incompleteness symptom*


The goal asks for the membership of a generic point (X,Y) to the intersection of the two rectangles (rect (20,20) 50 20) and (rect (5,5) 30 40), computed indirectly as the first steps of two particular ladders. The diagram included in Fig. 1 shows these two rectangles as well as the rectangle corresponding to their intersection (highlighted in black). The T OY system has solved the goal by a combination of lazy narrowing and constraint solving; the computed answer consists of the substitution R –> true and three constraints imposed on the variables X and Y1. The only constraint imposed on Y (namely Y <= 5) allows for arbitrarily small values of Y, which cannot correspond to points belonging to the rectangle expected as intersection. Therefore, the user will view the computed answer as *wrong* with respect to the intended meaning of the program. As we will see in Sections 4 and 5, the declarative debugging technique presented in this chapter leads to the diagnosis of the program rule for the function rect as responsible for the *wrong answer*. Indeed, this program rule is incorrect with respect to the intended program semantics; as shown in Fig. 1, the third inequality at the right hand side should be Y' >= Y instead of Y' <= Y.

After this correction, no more wrong computed answers will be observed for the goal discussed above. As any debugging technique, declarative diagnosis has limitations. A "corrected" program fragment can still include more subtle bugs that can be observed in the computed answers for other goals. In our case, we can consider the goal

Toy> /cflpr Toy(R)> intersect (head (ladder (70,40) -50 -20)) (head (ladder (35,45) -30 -40)) (X,Y) == R

whose meaning with respect to the intended semantics is the same as for the previous goal, except that the rectangles playing the role of initial steps of the two ladders are represented differently. Since the boolean expression at the right hand side of the "corrected" program rule for function rect yields the result false whenever LX or LY is bound to a negative number, wrong answers including the substitution R –> false will be computed. Moreover, other answers including the substitution R –> true will be expected by the user but *missing* to occur among the computed answers.

The traditional approach to declarative debugging in the *CLP*(D) scheme includes the diagnosis of both *wrong* and *missing* computed answers (Tessier & Ferrand, 2000). Now, we motivate our approach for the declarative debugging of *missing answers* in the *CFLP*(D) scheme by means of the following example, intended to illustrate the main features of our diagnosis method.

<sup>1</sup> There are other five computed answers consisting of the substitution R –> false and various constraints imposed on X and Y.
