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

4 Will-be-set-by-IN-TECH

(head (ladder (5,5) 30 40)) (X,Y) == R % goal {R–> true } { Y <= 5, X >= 2.0E+01, X <= 35 } % computed answer

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

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

(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 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

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

computed answers for other goals. In our case, we can consider the goal

Toy> /run(examples/debug/ladder) % compile *ladder.toy* Toy> /cflpr % load *CFLP*(R)

Toy(R)> intersect (head (ladder (20,20) 50 20))

should be Y' >= Y instead of Y' <= Y.

Toy(R)> intersect (head (ladder (70,40) -50 -20))

Toy> /cflpr

the computed answers.

diagnosis method.

imposed on X and 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 the program defined functions as possibly non-deterministic.

```
infixr 40 // % non-deterministic choice operator
(//) :: A -> A -> A
X // _ --> X
_ // Y --> Y
fDiff :: [A] -> A
fDiff [X] --> X
fDiff (X:Y:Zs) --> X // fDiff (Y:Zs) <== X /= Y
fDiff (X:Y:Zs) --> X <== X == Y
gen :: A -> A -> [A] even :: int -> bool
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* could be mended by placing again the third rule for fDiff within the program.
