Declarative Debugging in Constraint Logic Programming: the Cover Relation

advertisement
Declarative Debugging in
Constraint Logic Programming:
the Cover Relation
Alexandre Tessier
LIFO, Universite d'Orleans
BP 6759, 45067 Orleans Cedex 2, France
Alexandre.Tessier@lifo.univ-orleans.fr
ftp://ftp-lifo.univ-orleans.fr/pub/Users/tessier/
http://www.univ-orleans.fr/~tessier
fax: (+33) 38417137, phone: (+33) 38494670
Abstract
This work is motivated by the declarative insuciency diagnosis of constraint logic
programs, but focuses only, in this paper, on theoretical viewpoints. Many techniques
have been developed for logic programming but cannot be merely adapted to constraint
logic programming. An answer is not covered by a more general computed answer any
more. Practical implementations use incomplete solvers with regard to theoretical
framework of CLP (Jaar and Lassez 1986) based on a theory or a domain. New
theoretical foundations are necessary. Constraint logic program semantics is redened
in terms of proof trees using a cover relation. Proof trees give an intrinsic denition to
the answers provided by a program. The cover relation expresses that a constraint is
covered by a (possibly innite) constraint set. Thus we give a theoretical framework
where declarative diagnosis method can be studied thanks to the inductive nature of
the semantics. We dene the notions of symptoms and errors and we prove that if
there exists a symptom then there exists an error.
1
Contents
1 Introduction
2 Preliminaries
3 Operational Semantics
3.1
3.2
3.3
3.4
Skeletons : : : : : : : :
Reject Criterion : : : :
Answers : : : : : : : :
Resolution : : : : : : :
3.4.1 SLD-Resolution
3.4.2 SLD-tree : : : :
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
4 Declarative Semantics
4.1
4.2
4.3
4.4
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
Cover Relation : : : : : : : : : : : : : : : : : : : :
Proof Trees : : : : : : : : : : : : : : : : : : : : : :
Correspondance betwwen Proof Trees and Skeletons
Declarative Semantics : : : : : : : : : : : : : : : :
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
3
6
9
9
12
13
13
14
15
16
16
17
19
20
5 Declarative Insuciency Diagnosis
24
6 Conclusion
30
5.1 Denitions : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 25
5.2 Diagnosis Algorithm : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 29
2
1 Introduction
Program debugging is known to be a time consuming task in the programming process. For a
large broadcasting, Constraint Logic Programming (CLP) systems must integrate debugging
tools.
A great strength of Constraint Logic Programming (CLP) is its declarative nature. For a
declarative language (with a semantics independent of its execution model), it is essential to
consider a declarative error notion. Indeed, it is incoherent to use only low level debugging
tools based on an understanding of the operational behaviour of the system and to give up
a high level knowledge of the declarative meaning of the programs.
But, the success of a declarative debugging tool is directly related to the language declarativity level. From this viewpoint, CLP is used in a much more declarative way than LP.
In particular, the availability of global constraints and disequations makes useless: negation by failure, \cut", \is", meta-predicate such \var", etc. For these reasons, an essential
component of a complete CLP system should be a declarative debugging tool.
In this context, declarative means that the user does not need to understand the operational behaviour of the system. It is evident that a computer cannot diagnose errors in a
program without being told a part of what should be computed by the program. But, only
the intended declarative semantics of the program is required.
Declarative error diagnosis in Logic Programming (LP) was introduced by E. Y. Shapiro
[27] under the name of algorithmic debugging. Many techniques inspired by the Shapiro's
method have been developed for logic programs [12, 11, 21, 8, 13, 7, 9, 22, 24, 3]. But,
declarative diagnosis of constraint logic programs is relatively unexplored. We focus in this
paper on the theoretical aspects of the declarative insuciency diagnosis of constraint logic
programs. That is, how to declaratively point a small piece of erroneous code when an answer
is lacking.
Declarative debugging algorithms usually proposed in LP strongly use the Herbrand's
models properties. Known LP techniques cannot be straightforwardly adapted to CLP:
In CLP, Herbrand's interpretations do not represent program semantics any more.
Some elements of the constraint domain are not nitely expressible in the program
language (e.g. in CLP(R) [17]). But when we debug we would stay in the program
language.
How can we express that an answer misses because of some domain values? In fact,
elements of the domain are only manipulated through constraints.
In LP, each answer, which is a logical consequence of the program, is covered by a
single more general computed answer. In CLP, there is no single cover any more.
A sucient condition for the single cover property is the Independence of Negated
Constraint (INC) [23] which is, unfortunately, veried by few interesting constraint
domains.
For example, in CLP(R), let us consider the program:
p(x)
p(x)
3
x<0
x0
Assume that for the goal p(x) we expect the answer true. Must we consider true as
an insuciency symptom and the previous program as wrong? In fact, the IR-theory
has for logical consequence 8x(true ! (x < 0 ^ x 0)). So it is not because true does
not occur (in the less general sense) in the answer set fx < 0; x 0g that an answer
is lacking. We must consider the whole answer set and check if it covers the expected
answer.
We start in reformulating program semantics bases. Our approach of constraint logic
program semantics in terms of proof trees based on a cover relation is an extension of the
grammatical view of LP [10, 4]. Proof trees give an intrinsic denition to the answers
provided by a program. Relations between declarative semantics and operational semantics
is then better explain. The cover relation expresses that a constraint is covered by a (possibly
innite) constraint set.
Practical implementations use incomplete constraint solvers with regard to theoretical
framework [18] based on a theory or a domain. Our semantics abstract the constraint
interpretation. Then, the constraint interpretation by a domain D or a (non satisfaction
complete) theory T or an (incomplete) constraint solver A becomes particular case. We
show that classical semantics [18, 14, 23, 19, 29, 19] are instance of our own. We can remark
that the three previous possible constraint interpretations have not the same behaviours:
T (or D) vs. A.
For example, the constraint solver of CLP(R) provides three kinds of answers: yes
(satisable constraint), no (unsatisable constraint), maybe (it cannot decide). It answers yes for x x = 1 ^ x = 1 and maybe for x x = 1, nevertheless j= 9x(x x =
1 ^ x = 1) ! 9x(x x = 1) (where j= F means that F is a logical consequence of the
empty theory); it answers no for x = 1 ^ x = 0 and maybe for x x = 1 ^ x x = 0,
nevertheless j= :9x(x = 1 ^ x = 0) ! :9x(x x = 1 ^ x x = 0).
T vs. D.
Let us consider the program
ent(x) x = 0
ent(x) x = y + 1; ent(y)
When constraint interpretation is the domain IN, the declarative answer true to the
goal ent(x) is not covered by a nite part of the computed answers fx = 0; x =
1; : : : ; x = i; : : :g. But when constraint are interpreted through a theory, a model of
which is IN, the declarative answer true is covered by a nite part of the computed
answers because of the compactness theorem of the rst order logic.
First, we give the operational semantics in terms of skeleton. Skeletons glue together
the clause used during the compitation leaving aside the computation rule. The operational
semantics is parametrized by a reject criterion which eliminates some unsatisable answer
constraints. The notion of domain or theory usual for the constraint interpretation becomes a
parameter of the reject criterion. Then we can take into account the incompleteness of some
constraint solvers which cannot be expressed in a logical framework as previously shown.
The system end the computation when the current store is rejected.
4
Next, we dene the declarative semantics. We introduce a cover relation between a
constraint c and a constraint set C , denoted by c ` C and read: c is covered by C . The
cover relation abstracts the dierent previous cover notions. When C = ; we nd the reject
criterion. Thus, it generalizes the reject criterion. We nd the entailment relation when C is
a singleton, [26] shows the interest of a framework based on an abstract entailment relation
rather than a domain or a theory. The semantics is given in term of proof tree roots build
on two kinds of rule: the program rules and the cover rules. The proof trees determine
the declarative semantics while the proof trees which only use program rules determine an
abstraction of the operational semantics.
On the one hand, for each complete proof tree, there exists a complete proof tree with
the same conclusion which uses a single cover rule, and this cover rule is used at the proof
tree root. Thus, we rediscover well known results when the cover relation is deduced from a
domain or a theory. On the other hand, for each complete proof tree, there exists a complete
proof tree with the same conclusion which alternates program rules at even depth and cover
rules at odd depth. The previous results are essential because they assert that, on the one
hand, answers dened by covering computed answers and, on the other hand, answers dened
by applying alternately program rules and cover rules are exactly all the declarative answers.
They guarantee the consistency of denitions and results of our declarative diagnosis method.
The inductive nature of our semantics is adapted to study declarative diagnosis in the
algorithmic debugging way.
In this framework, where we just consider missing answers, two notions of symptoms
are dened: incompleteness symptoms and insuciency symptoms. Two associated kinds of
errors are dened: non covered constrained atoms which are called strong insuciencies and
non completely covered constrained atoms called weak insuciencies. We prove that is there
exists a symptom then there exists an error. The two kinds of symptoms and errors are
known in LP [27, 12, 11], but were dened into dierent frameworks. Thus, we contribute
to better understand and compare them.
Finally, we propose a diagnosis algorithm which given a computed symptom, that is a
goal a which provides a nite standard SLD-tree such that an answer is missing, localizes
an error (weak insuciency) in the program through implementation independent interaction
with the expected semantics (the oracle).
The rest of the paper is organized as follow: Sect. 2 denes the program language and
some notations. The operational semantics is introduced in Setc. 3. Sect. 4 denes the
declarative semantics, it presents the cover relation and its properties. Sect. 5 studies the
declarative insuciency diagnosis. The conclusion recapitulates main ideas and the works
in progress.
5
2 Preliminaries
Let us consider once and for all four sets which dene the program language:
an innite set of variables V ;
a set of function symbols ;
a set of constraint predicate symbols c;
a set of program predicate symbols p.
The term set is built as usual on V; . Atomic formulas build on V and p of the
form p(x ; : : : ; xn), where p is a n-ary predicate symbol of p and x ; : : : ; xn are n distinct
variables, are called atoms. The constraint language CONST is a subset of the rst order
language build on V , and c. We assume that it is closed under conjunction and existential
quantication. A constraint is a formula of CONST.
Let us introduce some notations:
x~ denotes a sequence of distinct variables x ; : : : ; xn.
If F is a formula (built on V , , p [ c) then var(F ) denotes the free variable sequence
of F .
If c is a constraint, x~ is the variable sequence x ; : : : ; xn , y~ are the free variables of c
not in x~ and a is an atom then
{ 9x c denotes 9x 9xn c,
{ 9 x c denotes 9y c,
{ 9 a c denotes 9 var a c.
A clause is a (n + 2)-tuple (0 n) denoted by a
c 2 a ; : : : ; an, where each ai is
an atom and c is a constraint. When n = 0, the clause is called a fact. This denition is
equivalent to the denition of [19]. Given a clause R of the previous form, we dene
head(R) = a ,
body(R) = c 2 a ; : : : ; an,
constraint(R) = c,
arity(R) = n.
A program is a set of clauses. A constrained atom is a pair a[c] where a is an atom and c is
a constraint.
In order to simplify we consider atomic goals rather than general goals. Indeed, given a
general goal c 2 a ; : : : ; an we can add a clause p(~x) c 2 a ; : : : ; an, where p is a new
predicate symbol and x~ = var(c 2 a ; : : : ; am), then we can consider answers to the atomic
goal p(~x). Thus a goal is a, where a is the atom.
1
1
1
1
~
1
~
~
( )
0
1
0
1
1
1
1
6
Remark. A general goal g denes a new relation whose arity is the number of free variables
of g. Let ansg be this relation (ansg 62 p [ c). Let us consider the program Pans built on
V; ; c; p [fansg j g is a goal for P g and denes as follow: Pans = P [fansg (var(g))
g j gis a goal for P g. The language of P determines the language of Pans and given P
we can determine Pans. The predicates added to the language do not occur in the clause
body of Pans. Then, an answer to a general goal g for P is an answer to the goal
ansg (var(g)) for Pans. But the notation would be less readable if we consider the two
programs P and Pans. Thus we just consider the program P and answers to atomic goal for
P . Moreover, the set of answers to the general goal c 2 a1; : : : ; an can be easily dened
as the set fc ^ c1 ^ ^ cn j ci is an answer to ai , for i = 1; : : : ; n and c ^ c1 ^ ^ cn is
\satisable"g.
This paper is illustrated by the example of defective components detection in a binary
adder. This example, in Prolog III with booleans [2], is due to A. Colmerauer [6]. The reader
must not confuse our aim which is to diagnose error in a program and the example which
detects a defective component in a binary adder.
Example 1 We are interested in detecting the defective components in a binary adder which
computes the binary sum of three bits X1,X2,X3 in the form of a binary number given in two
bits Y1,Y2.
X1
P1
AND
AND
P4
XOR
OR
P2
X2
X3
P3
U1
Y1
U2
P5
XOR
U3
Y2
The binary adder.
We are only interested, in the following program DETECT1 (write in PROLOG III with the
edinburgh syntax), by the case where a single component is defective.
go(C,E,S) :circuit(C,E,S),
enu(E)
{C = [0',0',0',0',1'], S = [1',1']}.
circuit(C,E,S) :at_most_1(C,X)
{C = [P1,P2,P3,P4,P5], E = [X1,X2,X3], S = [Y1,Y2], X = 1',
~P1 => (U1<=>(X1&X3)), ~P2 => (U2<=>(X2&U3)),
~P3 => (Y1<=>(U1|U2)), ~P4 => (U3<=>~(X1<=>X3)),
~P5 => (Y2<=>~(X2<=>U3))}.
7
at_most_1(L,X)
{L = [], X = 0'}.
at_most_1(L,X) :at_most_1(Q,Z)
{L = [Y|Q], X = Y|Z, Y&Z = 0'}.
boolean(X)
{X = 0'}.
boolean(X)
{X = 1'}.
enu(L)
{L = []}.
enu(L) :boolean(X),
enu(Q)
{L = [X|Q]}.
circuit(C,E,S) expresses the relation between inputs, outputs and the defective component. C is the component list (P1 to P5), a component is defective when its value is 1', E is
the input list (X1,X2,X3) and S is the output list (Y1,Y2). U1,U2,U3 are outputs of component
P1,P2,P4.
go(C; E; S) provides the inputs when the component P5 is defective and in order to simplify
we impose that the outputs are 1',1'. Answers provided by PROLOG III to the goal
go(C; E; S) are:
?{C
{C
{C
{C
go(C,E,S).
= [0',0',0',0',1'],
= [0',0',0',0',1'],
= [0',0',0',0',1'],
= [0',0',0',0',1'],
E
E
E
E
=
=
=
=
[0',1',1'],
[1',0',1'],
[1',1',0'],
[1',1',1'],
S
S
S
S
=
=
=
=
[1',1']}
[1',1']}
[1',1']}
[1',1']}
First and third answers appear because a defective component does not always provide an
erroneous output (implications in the program).
8
3 Operational Semantics
This section briey describes operational semantics of programs. That is, given a program
P , how to build the answers to a goal a for P . It ends by the denition of SLD-tree useful
to dene the computed symptoms for declarative insuciency diagnosis in Sect 5.
We rst introduce the notion of skeleton which links operational semantics (derivations,
SLD-tree...) and declarative semantics (proof trees, xed point...) of a program. On the one
hand, skeletons describe the SLD-resolution. On the other hand, they provide an intrinsic
denition of answer notion. Thus, many results of independence of the selection rule can be
straightforwardly proved. But this is out the scope of this paper (the reader can see [4]).
3.1 Skeletons
A skeleton is an oriented tree, labeled by P [ f?g, such that, for each node N , let label(N )
be its label:
the degree of N is arity(label(N )) (arity(?) = 0);
if label(N ) = a c 2 a ; : : : ; an then N has n children N ; : : : ; Nn such that, for each
0
1
1
i = 1; : : : ; n, label(Ni ) is
{ either ?
{ or a clause Ri of P whose head predicate symbol is the same that the predicate
symbol of ai (see Ex. 2).
For each skeleton S , we denote by
undef (S ) the set of nodes of S labeled by ?;
def (S ) the set of the other nodes;
root(S ) its root.
Example 2 A skeleton for the program DETECT1:
go(C; E; S )
?
boolean(X )
C = [00; 00; 00; 00; 10] ^ S = [10; 10] 2 circuit(C; E; S ); enu(E )
enu(L)
@
L = [X jQ] 2 boolean(X ); enu(Q)
X = 10 2
boolean(X )
enu(L)
X = 10 2
boolean(X )
@
L = [X jQ] 2 boolean(X ); enu(Q)
@
enu(L)
X = 00 2
L = [X jQ] 2 boolean(X ); enu(Q)
@
enu(L)
9
L = [] 2
A renaming function for a skeleton S , is a mapping choice (from nodes to P [ f?g) in
the following way: for each node N of S
if N = root(S ) then choice(N ) = label(N );
if N is a leaf labeled by ? (label(N ) = ?) then choice(N ) = label(N );
otherwise choice(N ) = label(N ), where is a renaming such that:
{ if N is the i child of N 0 then the i atom of body(choice(N 0 )) is head(choice(N )),
{ for each node N 0 which is not in the subtree rooted by N , for each variable
x 2 var(body(choice(N ))) var(head(choice(N ))), x has no free occurrence in
choice(N 0 ).
Intuitively, for each node of the skeleton except the root, we choose a variant of its label.
Thanks to the standard form of the program (i.e. arguments of the atoms are distincts
variables), we choose a variant whose head is syntactically identical to the corresponding
atom of the body of the variant of the clause choosen for its father and such that the new
variables (i.e. variables of the body which do not occur in the head) of the variant are
dierent of the new variables of the variant choosen for the other nodes.
We associate to each skeleton S and each renaming function choice for S the constraint
system const(S; choice) = fconstraint(choice(N )) j N 2 def (S )g. Renaming function just
determines renaming of constraint system variables. It is necessary to handle the constraints
as a system rather than a formula with quantiers, then innite constraint systems can
be considered. The system is sometimes denoted const(S ). It is dened up to a variable
renaming.
When def (S ) is nite, we denote by
conj (S; choice) the conjunction of the constraints of const(S; choice),
AC (S ) the constraint 9 x conj (S; choice), where x~ are the variables of the head of
choice(root(S )).
AC (S ) does not depend on the renaming function but only on var(head(label(root(S )))).
AC (S ) is called the constraint associated to S .
th
th
~
Example 3 We show the skeleton of Ex. 2 where clauses are renamed according to a renaming
function.
go(C; E; S )
?
boolean(X 0 )
C = [00; 00; 00; 00; 10] ^ S = [10; 10] 2 circuit(C; E; S ); enu(E )
@
E = [X 0jE 0] 2 boolean(X 0 ); enu(E 0)
enu(E )
X 0 = 10 2
boolean(X 00 )
enu(E 0)
X 00 = 10 2
boolean(X 000 )
@0
E = [X 00 jE 00] 2 boolean(X 00 ); enu(E 00)
enu(E 00)
X 000 = 00 2
@
E 00 = [X 000jE 000 ] 2 boolean(X 000 ); enu(E 000)
@
enu(E 000)
10
E 000 = [] 2
The constraint system is
f C = [00; 00; 00; 00; 10] ^ S = [10; 10];
E = [X 0 jE 0];
X 0 = 10;
E 0 = [X 00jE 00];
X 00 = 10;
00
E = [X 000 jE 000];
X 000 = 00;
E 000 = []
g
Its associated constraint is
9X 09E 0 9X 009E 00 9X 000 9E 000 (C = [00; 00; 00; 00; 10] ^ S = [10; 10] ^ E = [X 0jE 0]^
X 0 = 10 ^ E 0 = [X 00jE 00] ^ X 00 = 10 ^ E 00 = [X 000jE 000 ] ^ X 000 = 00 ^ E 000 = [])
It simplied by Prolog III into
C = [00; 00; 00; 00; 10] ^ S = [10; 10] ^ E = [10; 10; 00]
A complete skeleton is a skeleton S such that undef (S ) = ;. Finite complete skeletons
dene general answers of a program, in the sense that, if S is a nite complete skeleton
rooted by a g then P j= AC (S ) ! a.
Example 4 If we plug the following nite complete skeleton:
circuit(C; E; S ) C = [P 1; P 2; P 3; P 4; P 5] ^ E = [X 1; X 2; X 3] ^ S = [Y 1; Y 2] ^ X = 1 ^
P 1 ) (U 1 , (X 1&X 3))^ P 2 ) (U 2 , (X 2&X 3))^ P 3 ) (Y 1 , (U 1jU 2))^
P 4 ) (U 3 , (X 1 , X 3))^ P 5 ) (Y 2 , (X 2 , U 3)) 2 at most 1(C; X )
0
at most 1(C; X )
C = [Y jC ] ^ X = Y jX ^ (Y &X ) = 00 2 at most 1(C ; X )
at most 1(C ; X )
C = [Y jC ] ^ X = Y jX ^ (Y &X ) = 00 2 at most 1(C ; X )
at most 1(C ; X )
C = [Y jC ] ^ X = Y jX ^ (Y &X ) = 00 2 at most 1(C ; X )
at most 1(C ; X )
C = [Y jC ] ^ X = Y jX ^ (Y &X ) = 00 2 at most 1(C ; X )
at most 1(C ; X )
C = [Y jC ] ^ X = Y jX ^ (Y &X ) = 00 2 at most 1(C ; X )
1
2
3
4
1
2
3
4
1
1
2
3
4
2
3
4
5
1
1
2
1
1
3
2
2
4
5
5
5
3
4
4
at most 1(C ; X )
2
3
3
1
4
5
5
1
2
1
2
3
3
4
4
5
5
1
2
3
4
5
2
3
4
5
C = [] ^ X = 00 2
5
5
in the undened leaf of the skeleton of Ex. 3 then we obtain a nite complete skeleton whose
associated constraint is simplied by PROLOG III into
C = [00; 00; 00; 00; 10] ^ E = [10; 10; 00] ^ S = [10 ; 10]
11
3.2 Reject Criterion
Some general answers are less interesting. For example, if AC (S ) is always false then
AC (S ) ! a is always true regardless of the program. From a theoretical viewpoint, these
answers are not interesting. From an operational viewpoint, we have to avoid useless investigation which are possibly innite. The system tries to eliminate these \trivial answers"
thanks to a reject criterion. The operational behaviour of the program is parametrized by
this reject criterion.
A reject criterion, denoted by ` ;, is a relation over CONST. It can take into account
the working of an interpreter which provides answers with the comment maybe, indicating
that the (incomplete) constraint solver answers neither yes nor no. Reject criterion abstract
constraint interpretation. It is a relation over constraints in a syntactic way.
In order to simplify, we assume, to the paper end, that if c and c are two constraints
then:
c ^ c and c ^ c are the same constraint;
if x is a free variable of c which has no free occurrence in c then (9x c ) ^ c and
9x (c ^ c ) are the same;
if x and y are two variables then 9x9y c and 9y9x c are the same,
if x is a variable then 9x c and 9x9x c are the same.
For each rejected constraint c, denoted by c ` ;, the reject criterion ` ; veries the three
following properties:
CONJ : for each constraint c0, c ^ c0 ` ;;
EXIS : for each variable x, 9x c ` ;;
RENA : for each renaming , c ` ;.
Reject criterion is not any one. In general, it is dened from:
a domain D, denoted by `D ;, then c `D ; if, for each valuation v in D, v(c) is false;
a theory T , denoted by `T ;, then c `T ; if, for each model D of T , c `D ; (i.e.
T j= :c);
a constraint solver A, denoted by `A ;, then c `A ; if the solver answers no for the
satisability of c.
Thanks to the reject criterion, the operational semantics can be studied by abstracting
the constraint interpretation. Thus, we can take into account the behaviour of an incomplete
constraint solver.
1
1
2
2
1
1
1
2
2
2
1
1
1
12
1
1
2
3.3 Answers
We assume that a reject criterion ` ; and a program P are xed.
Denition 3.1
1. A skeleton S is rejected if there exists a nite subset C of const(S ) such that Vc2C c ` ;
(note that S nite is rejected i AC (S ) ` ;).
2. An answer to the goal a is a non rejected nite complete skeleton S rooted by a
variant of a clause whose head is a. Then AC (S ) is an answer constraint to the goal
a.
Example 5 The skeleton of Ex. 4 plug in the undened leaf of the skeleton of Ex. 3 is an
answer to the goal go(C; E; S ), its constraint system is not rejected. The answer constraint
is:
9E 0 9X 09E 00 9X 00 9E 000 9X 0009P 19P 29P 39P 49P 59X 19X 29X 39Y 19Y 29U 19U 29U 3
9Y 9C 9X 9Y 9C 9X 9Y 9C 9X 9Y 9C 9X 9Y 9C 9X
0
0
0
(C = [0 ; 0 ; 0 ; 00; 10] ^ S = [10 ; 10] ^ E = [X 0 jE 0] ^ E 0 = [X 00jE 00] ^ E 00 = [X 000jE 000 ] ^ E 000 =
[] ^ X 0 = 10 ^ X 00 = 10 ^ X 000 = 00 ^ C = [P 1; P 2; P 3; P 4; P 5] ^ E = [X 1; X 2; X 3] ^ S =
[Y 1; Y 2] ^ X = 10^ P 1 ) (U 1 , (X 1&X 3))^ P 2 ) (U 2 , (X 2&X 3))^ P 3 )
(Y 1 , (U 1jU 2))^ P 4 ) (U 3 , (X 1 , X 3))^ P 5 ) (Y 2 , (X 2 , U 3)) ^ C =
[Y jC ] ^ X = Y jX ^ (Y &X ) = 00 ^ C = [Y jC ] ^ X = Y jX ^ (Y &X ) = 00 ^ C =
[Y jC ] ^ X = Y jX ^ (Y &X ) = 00 ^ C = [Y jC ] ^ X = Y jX ^ (Y &X ) = 00 ^ C =
[Y jC ] ^ X = Y jX ^ (Y &X ) = 00 ^ C = [] ^ X = 00)
1
1
1
3
3
2
1
1
2
2
2
3
3
3
4
4
4
5
5
5
1
1
1
1
1
2
2
1
2
2
2
2
2
3
3
3
3
3
4
4
3
4
4
4
4
4
5
simplied into:
5
4
5
5
5
5
5
5
C = [00; 00; 00; 00; 10] ^ S = [10; 10] ^ E = [10; 10; 00]
3.4 Resolution
We describe now a process which provides all the answers for a goal a. It is possible to
generate all the nite skeletons rooted by a clause whose head is a, but for ecient purpose,
we want to build only skeletons which are susceptible to be non rejected.
The skeleton S is a sub-skeleton of the skeleton S if S coincide with S on def (S ).
Thus, def (S ) def (S ) and S is obtained by labelling by ? some nodes of S (their
children are removed).
If S is a sub-skeleton of S then each renaming function choice for S can be extended in
a renaming function choice for S such that, if N 2 def (S ) then choice (N ) = choice (N ).
Thus, const(S ; choice ) const(S ; choice ) and, consequently, each sub-skeleton of a non
rejected skeleton is not rejected (CONJ property of ` ;).
2
1
2
1
2
2
2
1
2
2
1
1
2
1
2
1
2
1
1
13
2
1
2
3.4.1 SLD-Resolution
The top-down resolution consists in building skeletons obtained by plugging in undened
leaves other skeletons, until it is an answer.
A skeleton S 0 derives from a non rejected skeleton S by the leaf N 2 undef (S ) if S 0 is
not rejected and there exists R 2 P such that S 0 is obtained from S by plugging sq(R) in
N , where sq(R) is the skeleton whose root is labeled by R and has arity(R) children labeled
by ?.
The SLD-derivation is a top-down resolution which, given a goal a, builds a sequence
of non rejected nite skeletons rooted by renamed clause R such that head(R) = a, in the
following way: rst state is sq(R),
1. if sq(R) is rejected then there is no answer, the resolution end;
2. from the state S ,
if S is complete then S is a computed answer;
otherwise, the following state is a skeleton S 0 which derives from S .
S is a nal state when no state derives from S . Then S is a success state if S is complete,
otherwise it is a failure state.
We call SLD-derivation every (nite or innite) state sequence S ; : : : ; Si; : : : such that
S = sq(R), each state (except the rst one) derives from the previous and the sequence is
innite or the last state is a nal state.
1
1
Lemma 3.2 The SLD-resolution has the two following properties:
1. each computed answer is an answer;
2. it computes all the answers.
Proof.
1. The rst property is obvious: the SLD-resolution only build non rejected nite skeletons
rooted by a renamed clause R whose head is a.
2. To prove the second one, let us consider an answer S for the goal a. The breadth
rst traversal of S provide a sequence of nodes N ; : : : ; Nm . We dene the sequence
of skeletons S ; : : : ; Sm: Si is a sub-skeleton of S such that def (Si) = fN ; : : : ; Nig.
Then, it is easy to show that S ; : : : ; Sm is a SLD-derivation and Sm = S , thus S is a
computed answer.
1
1
1
1
The SLD-resolution is twice non deterministic:
the choice of the leaf where the skeleton is plugging in,
the choice of the clause which roots the plugged skeleton.
14
We call computation rule a mapping r which, for each incomplete skeleton S in a derivation,
provides a leaf in undef (S ). Given a computation rule r, the SLD-resolution according to r
for a goal a is a SLD-resolution for the goal a where, at each step S , the choosen leaf
is r(S ).
3.4.2 SLD-tree
Denition 3.3 A SLD-tree for the goal
p(~x) is a (possibly innite) tree A rooted by
p(~x), with nodes, expect the root, labeled by non rejected nite skeletons such that:
a node labeled by an answer S has no child, it is a success node and S is a computed
answer;
if R ; : : : ; Rn are the clause of the denition of p and ; : : : ; n are variable renamings
such that head(Ri )i = p(~x), for i = 1; : : : ; n then the root has n child labeled by
sq(Rii ), for i = 1; : : : ; n;
for each node M of A (expect the root) labeled by an incomplete skeleton S , let N 2
undef (S ), children of M exactly correspond to skeletons which derive from S by N
and they are labeled by these skeletons, if M has no children then M is a failure node.
1
1
A Branch of a SLD-tree for a correspond to a SLD-derivation for a. A success
branch (resp. failure, innite) correspond to a success SLD-derivation (resp. failure, innite).
Lemma 3.4 S is a computed answer to the goal
a i S is an answer to the goal a.
Proof. There exists a one-to-one correspondence between success branches of an SLD-tree
for the goal a and answer skeletons to the goal a.
The standard strategy is based on the computation rule which choose the left most undened leaf. The SLD-tree for a according to the computation rule r is the SLD-tree such
that, for each node labeled by an incomplete skeleton S , the chosen leaf is r(S ).
Lemma 3.5 The computed answers are independent of the computation rule.
Proof. Answer skeletons are independent of the computation rule and there exists a one-toone correspondence between success branches of an SLD-tree for the goal a and answer
skeletons to the goal a.
15
4 Declarative Semantics
In LP, a declarative answer to the goal a is a substitution such that P j= a. For
each declarative answer substitution, there exists a single more general computed answer
substitution. The similar results in CLP should be that, if P j= c ! a (or P; T j= c ! a or
P j=D c ! a) then there exists a single computed answer constraint c0 to the goal a such
that c0 is \more general" than c. It is well known that this is wrong in general . Nevertheless,
we would keep a similar property which links declarative answer constraints and computed
answer constraints. In fact, each declarative answer is covered by a (possibly innite) set of
computed answers. This relation is called the cover relation.
Our declarative semantics has no logical nature. It is dened inductively by two kinds of
rules. First rules stem from clauses of the program and the second ones are dened from the
cover relation. We nd again every known results when the cover relation is deduced from a
domain or a theory.
1
4.1 Cover Relation
A cover relation ` is a binary relation over CONST 2CONST. It veries, for each constraint
c, the six following properties:
CONJ : let c ; : : : ; cn be n constraints and C ; : : : ; Cn be n constraint sets such that ci ` Ci,
i = 1; : : : ; n, then c ^ ^ cn ` fc0 ^ ^ c0n j c0i 2 Ci; i = 1; : : : ; ng
REFL : c ` fcg;
EXIS : let x~ be a variable sequence and C be a constraint set such that c ` C , then
9x c ` f9x c0 j c0 2 C g;
TRAN : let C be a constraint set such thatSc ` C and (Cc0 )c 2C be a constraint set family
such that c0 ` Cc0 , for c0 2 C , then c ` c 2C Cc0 ;
MONO : let C; C 0 be two constraint sets such that c ` C and C C 0, then c ` C 0 ;
RENA : let be a variable renaming and C be a constraint set such that c ` C , then
c ` fc0 j c0 2 C g.
1
1
1
~
1
~
0
0
0
0
0
The cover relation extends the reject criterion. A constraint is rejected when it is covered
by the empty set. We recognise the three properties (CONJ, EXIS, RENA) of reject
criterions.
(CONST; `) denes a constraint system in a sense similar to [26, 15, 5].
In general, the cover relation is deduced from:
a domain D, denoted by `D , c `D C if for each valuation in D which satises c there
exists a constraint in C satised by the valuation;
a theory T , denoted by `T , c `T C if, for each model D of T , c `D C ;
1
These property is veried when there is the Independence of Negated Constraint [23].
16
a constraint solver A, denoted by `A and dened by the least relation verifying the ve
properties and such that c `A ; if the constraint solver answers no for the satisability
of c.
Thanks to the cover relation, which generalizes the reject criterion, we can elaborate a
semantics which takes into account the dierent constraint interpretations. Interest of this
novel semantics is to study the declarative insuciency diagnosis and to dene the notion
of symptoms and errors for constraint programs.
4.2 Proof Trees
The semantics is described in terms of root of proof trees built on a rule system. There is
two kind of rules: the rst ones are dened by the clause of the program and the second
ones are dened by the cover relation.
Denition 4.1
Program Rules
For each renamed clause a
dene the program rule:
c 2 a ; : : : ; an of P and each constraint c ; : : : ; cn, we
1
1
a [c ] an[cn]
a[9 a (c ^ c ^ ^ cn)]
1
1
1
when n = 0 we deduce the axiom a[9 c] .
a
Cover Rules
For each atom a, each constraint c and each constraint set C such that c ` C , we dene
the cover rule:
fa[c0 ] j c0 2 C g
a[c]
when C = ; we deduce the axiom a[c] .
As to each rule system, we associate, in the classical way, a notion of proof trees [1]. Proof
trees which use the two kinds of rule determine the declarative semantics while proof trees
which only use program rules determine an abstraction of the operational semantics.
Denition 4.2
An answer to the goal a is the root a[c] of a proof tree.
A computed answer to the goal a is the root a[c] of a proof tree which only use
program rules.
17
Answers and computed answers dened in Sect 3 are called answer skeletons and computed answer skeletons.
Remark. When c ` ;, for each atom a, a[c] is an answer. Then a[c] is called a trivial answer
to a according to `. It is independent of the program. The system tries to eliminate, as
far as possible, these trivial answers which have no interest for the user (see Sect 3.
For example, in CLP(R), consider the program:
p(x; y) x > y 2
q(x; y) v = x x ^ w = y y 2 p(v; w)
r(x) x = y 2 p(x; y)
r(x) x = y 2 q(x; y)
We obtain the two answers r(x)[x > x] and r(x)[x x > x x] to the goal r(x). According
to IR, both answer constraints are unsatisable. The rst one is removed, while the second
one is described as maybe.
Example 6 go(C; E; S )[C = [00 ; 00; 00 ; 00; 10] ^ S = [10; 10 ] ^ E = [00 ; 10; 10]] is a computed answer
to the goal go(C; E; S ). See the following proof, denoted by A , where constraints are
simplied for further legibility:
at_most_1(C 5,X5 )[C 5=[] X5 =0’]
at_most_1(C 4,X4 )[C 4=[1’] X4 =1’]
at_most_1(C 3,X3 )[C 3=[0’,1’] X3 =1’]
at_most_1(C 2,X2 )[C 2=[0’,0’,1’] X2 =1’]
boolean(X’’’)[X’’’=1’] enu(E’’’)[E’’’=[]]
at_most_1(C 1,X1 )[C 1=[0’,0’,0’,1’] X1 =1’] boolean(X’’)[X’’=1’] enu(E’’)[E’’=[1’]]
at_most_1(C ,X )[C =[0’,0’,0’,0’,1’] X =1’]
enu(E’)[E’=[1’,1’]]
boolean(X’)[X’=0’]
circuit(C,E,S) [C=[0’,0’,0’,0’,1’] S=[1’,1’] E=[0’,1’,1’]
enu(E)[E=[0’,1’,1’]]
go(C,E,S)[C=[0’,0’,0’,0’,1’] S=[1’,1’] E=[0’,1’,1’]
There exists a similar proof, denoted by B , for the computed answer go(C; E; S )[C =
[00; 00; 00; 00; 10] ^ S = [10; 10] ^ E = [10; 10; 00]].
From the cover rule stemming from 9A (E = [A; 10; A]) ` fE = [00; 10; 10]; E = [10 ; 10; 00]g
and the CONJ property of ` we deduce the answer go(C; E; S )[9A (C = [00 ; 00; 00; 00; 10]^S =
[10; 10] ^ E = [A; 10; A])] to the goal go(C; E; S ) and the proof:
A
B
0
0
0
0
0
go(C; E; S )[9A (C = [0 ; 0 ; 0 ; 0 ; 1 ] ^ S = [10; 10] ^ E = [A; 10; A])]
18
4.3 Correspondance betwwen Proof Trees and Skeletons
Given a nite complete skeleton S and a renaming function choice for S , we denote by
AP (S; choice) the tree which has exactly the same node that S up to their labels, and which
veries the following property: for each node N of AP (S; choice), let N 0 be the corresponding
node in S , SN the subtree of S rooted by N 0 and a = head(choice(N 0 )), N is labeled by
a[AC (SN )].
Given a proof tree A which only uses program rules, we denote by SQ(A) the tree which
has exactly the same node that A up to their labels, and which veries the following property:
for each node N of SQ(A), let N 0 be the corresponding node in A, N is labeled by the clause
which provides the program rule linking N 0 with its children.
0
0
Lemma 4.3
1. If S is a nite complete skeleton and choice is a renaming function for the skeleton S
then AP (S; choice) is a proof tree (only using program rules).
2. If A is a complete proof tree only using program rules and rooted by a[c] then SQ(A)
is a nite complete skeleton and AC (SQ(A)) = c.
3. a[c] is a computed answer to the goal a i there exists a nite complete skeleton S
such that head(root(S )) = a and AC (S ) = c.
Proof.
1. We prove the lemma by induction on the skeleton S .
If S is 1 high then it is rooted by the fact a c 2 . From this fact, we deduce
the program rule: a[9 c] . AP (S; choice) is the 1 high tree rooted by a[9 a c]
a
and it is a complete proof tree which only uses the previous program rule.
Let us assume that for each complete skeleton S whose height is h and for each
renaming function choice for S , AP (S; choice) is a complete proof tree only using
program rules.
Let S be a (h + 1) high complete skeleton and choice be a renaming mapping
for S . We have to show that AP (S; choice) is a complete proof tree only using
program rules.
Let N be the root of S and a c 2 a ; : : : ; an = choice(N ). The root of S has n
children S ; : : : ; Sn which are complete skeletons whose height h. Thus, for each
i = 1; : : : ; n, AP (Si; choiceSi ) is a complete proof tree only using program rules
(choiceSi is the renaming function for Si deduced from choice). The complete
proof trees AP (Si; choiceSi ) are rooted by ai[AC (Si)]. For each i = 1; : : : ; n, we
denote by 9 ai ci the constraint AC (Si ). AP (S; choice) is rooted by a[AC (S )].
On the one hand, the clause a c 2 a ; : : : ; an = choice(N ) provides the program
rule a[9a [9(9a1 c c] ^ a n [^9 9an cnc] )] . On the other hand, the constraint AC (S )
1
1
1
1
a
1
a1
1
an n
19
is 9 a (c ^ ^ cn). 9 a (9 a1 c ^ ^ 9 an cn) and 9 a (c ^ ^ cn) are the
same constraint because, for each i; j = 1; : : : ; n such that i 6= j , for each node
pair Ni of Si and Nj of Sj , the free variables of choice(Ni) which do not occur in
ai and the free variables of choice(Nj ) which do not occur in aj are separate, thus
9 ai ci ^ 9 aj cj and 9 ai 9 aj (ci ^ cj ) are the same constraint.
Therefore, AP (S; choice) is a complete proof tree only using program rules. It is
the tree rooted by the previous program rule and whose root has n children which
are the AP (Si; choiceSi ).
1
1
1
2. It is proved by induction on the proof tree A in the same way that the previous proof.
3. It is a consequence of 1. and 2.
The connection between proof trees and skeletons being clearly establish (a nite skeleton
is in connection with an equivalence class of proof trees), we denes declarative semantics
of a program as a constrained atom set called the success set. We distinguish two success
set, rst one describes theoretical operational semantics and second one describes declarative
semantics.
4.4 Declarative Semantics
We dene the semantics of a program as a constrained atom set called the success set. We
distinguish two success set, the rst one describes the operational semantics while the second
one describes the declarative semantics.
Denition 4.4
The success set associated to the program P is SS (P ) = fa[c] j a[c] is a computed
answerg.
The success set associated to the program P and the cover relation ` is SS`(P ) =
fa[c] j a[c] is an answerg.
Remark. Let us consider the subset SS `;(P ) of SS (P ) dened by SS `;(P ) = fa[c] j a[c] 2
SS (P ) and not(c ` ;)g, we show that (see [4])
SS ` ;(P ) = SS (P; T ) of [18],
SS ` ; (P ) = lfp(SPD ) of [19],
SS ` ; (P ) = SS (P; D) of [14].
SS `;(P ) = SSRC (P ) of [4] if the reject criterion RC is ` ;.
T
D
D
3
20
SS (P ) (resp. SS`(P )) is the set dened inductively by program rules (resp. program
rules and cover rules). Success sets can also be dened as least xed point of immediate
consequence operators linked with the two kinds of rules.
Denition 4.5 Let TP , T`, T`[;P et T`;P be the four immediate consequence operators (from
constrained atom sets to constrained atom sets), dened by:
TP (I ) = fa[c] j there exists a program rule a [c ]; a: :[c:]; an[cn]
such that ai [ci] 2 I , for each i = 1; : : : ; ng
0 0
T`(I ) = fa[c] j there exists a cover rule fa[c ] j c 2 C g
1
1
a[c]
such that a[c0 ] 2 I , for each constraint c0 2 C g
T`[;P (I ) = TP (I ) [ T`(I )
T`;P (I ) = T` (TP (I ))
Lemma 4.6
1. lfp(TP ) = TP " ! = SS (P )
2. SS`(P ) = fa[c] j there exists C , c ` C and a[c0 ] 2 SS (P ), c0 2 C g
3. lfp(T`[;P ) = T` (lfp(TP )) = T`(SS (P )) = SS` (P ) = T`[;P " ! + 1
4. lfp(T`[;P ) = lfp(T`;P )
Proof.
1. Consequence of the Knaster-Tarski's theorem.
2. Lemma is proved by induction on rules distinguishing the two cases corresponding to
the two kinds of rules.
(a) Let a[9a [cc ^] c ^an[c^n] c ] be a program rule.
a
n
Let us assume that, for each i = 1; : : : ; n, ai[ci] 2 SS`(P ) and there exists a
constraint set Ci such that ci ` Ci and, for each constraint c0i 2 Ci, ai[c0i] 2 SS (P ).
We have to show that there exists a constraint set C such that 9 a (c^c ^ ^cn ) `
C and, for each c0 2 C , a[c0] 2 SS (P ).
The program rule is deduced from the renamed clause a c 2 a ; : : : ; an.
Thus, for each n-tuple of constraint c0 ; : : : ; c0n such that, for each i = 1; : : : ; n,
0
0
c0i 2 Ci we have the program rule a[9a [cc ^] c 0 ^an[c^n] c0 ] , consequently a[9 a c ^
a
n
c0 ^ ^ c0n] 2 SS (P ).
1
1
1
1
1
1
1
1
1
1
21
The CONJ and REFL property of the cover relation guarantees that
c ^ c ^ ^ cn ` fc ^ c0 ^ ^ c0n j c0i 2 Ci; for each i = 1; : : : ; ng
The EXIS property of the cover relation guarantees that
9 a (c ^ c ^ ^ cn) ` f9 a (c ^ c0 ^ ^ c0n) j c0i 2 Ci; for each i = 1; : : : ; ng
Therefore, C = f9 a (c ^ c0 ^ ^ c0n ) j c0i 2 Ci; for each i = 1; : : : ; ng is sucient.
0 0
0
(b) Let fa[c ] aj [cc]2 C g be a cover rule.
Let us assume that, for each c0 2 C 0, a[c0] 2 SS`(P ) and there exists a constraint
set Cc0 such that c0 ` Cc0 and, for each constraint c00 2 Cc0 , a[c00 ] 2 SS (P ).
Then, we have to show that there exists a constraint set C such that c ` C and,
for each c00 2 C , a[c00] 2 SS (P ).
The cover rule is deduced from c ` C 0.
The TRAN property of the cover relation guarantees that
[ 0
Cc
c`
1
1
1
1
1
0
0
0
c 2C
0
0
0
Thus, C = Sc 2C Cc0 is sucient.
3. The proof is a direct consequence of 1. and 2.
4. It is straightforward to show that for each pair of constrained atom sets I; J if I J
then T`;P (I ) T`;P (J ), that is T`;P is monotonous (the rule system associated to this
operator can be dened from the composition of program rules with cover rules). Thus
T`;P has a least xed point.
lfp(T`;P ) T` (lfp(TP )) because the lfp(T`[;P ) = T` (lfp(TP )) and the REFL
property of `.
lfp(T`;P ) lfp(T`[;P ) because for each ordinal number , there exists an ordinal
number such that T`;P " T`[;P " .
It is also straightforward to show that: for each constraint set X , T`;P (T`[;P (X )) T`[;P (X ).
0
0
0
The least xed point of TP corresponds to roots of proof trees only using program rules,
the least xed point of T`[;P correspond to roots of proof trees and the least xed point of
T`;P correspond to roots of proof trees which use program rules at even depth and cover
rules at odd depth.
For each proof tree, there exists a proof tree with the same conclusion which uses a single
cover rule, and this cover rule is used at the proof tree root. Thus, we rediscover well known
results when ` is deduced from a domain or a theory. Our answer denition is equivalent to
the denition of [29] when ` is deduced from a domain.
22
Equalities of Lemma 4.6 are essential because they assert that, on the one hand, answers
dened by covering computed answers and, on the other hand, answers dened by applying
alternately program rules and cover rules are exactly all the answers. Equality of these three
sets guarantees consistency of denitions and results of Sect. 5.
23
5 Declarative Insuciency Diagnosis
This section extends, to CLP, works on declarative error diagnosis for LP based on the
Shapiro's method [27, 12, 21, 11, 7, 9].
Answers provided by a program are sometimes symptom of errors in the program. Error
diagnosis is error localization when a symptom (wrong answer or missing answer) is observed.
We just treat missing answers. Declarative incorrectness diagnosis (wrong answers) is studied
in the framework of Sect. 3 [20].
Example 7 In order to illustrate this section, we consider the program DETECT2 which is
an erroneous version of program DETECT1 of Ex. 1:
go(C,E,S) :circuit(C,E,S),
enu(E)
{C = [0',0',0',0',1'], S = [1',1']}.
circuit(C,E,S) :at_most_1(C,X)
{C = [P1,P2,P3,P4,P5], E = [X1,X2,X3], S = [Y1,Y2], X = 1',
~P1 => (U1<=>(X1&X3)), ~P2 => (U2<=>(X2&U3)),
~P3 => (Y1<=>(U1|U2)), ~P4 => (U3<=>(~X1&~X3)),
~P5 => (Y2<=>(~X2&~U3))}.
at_most_1(L,X)
{L = [], X = 0'}.
at_most_1(L,X) :at_most_1(Q,Z)
{L = [Y|Q], X = Y|Z, Y&Z = 0'}.
boolean(X)
{X = 0'}.
boolean(X)
{X = 1'}.
enu(L)
{L = []}.
enu(L) :boolean(X),
enu(Q)
{L = [X|Q]}.
24
Answers provided by Prolog III to the goal
?{C
{C
{C
; ; are:
go(C E S)
go(C,E,S).
= [0',0',0',0',1'], E = [0',1',0'], S = [1',1']}
= [0',0',0',0',1'], E = [1',0',1'], S = [1',1']}
= [0',0',0',0',1'], E = [1',1',1'], S = [1',1']}
Our purpose is to elaborate an algorithm which assists the user, as well as possible, to
search, through all the program, errors when an answer is missing. We would like to call
the algorithm in the following case: answers to the goal a are c ; : : : ; cm , the constrained
atom a[c] is expected but c is not covered by c ; : : : ; cm.
1
1
5.1 Denitions
The intended semantics of a program P is formalized by a constrained atom set denoted by
I.
We say that the program P is nitely incomplete according to I for the atom a if there
exists a nite SLD-tree for the goal a whose success constitute the constraint set C and
there exists a constraint c such that a[c] 2 I and not(c ` C ). Then, a[c] is called a computed
symptom. Thus, a computed symptom is an element of I which is not in T` (lfp(TP )). We
recall, once more, that T`(lfp(TP )) = lfp(T`[;P ) = lfp(T`;P ).
Example 8 go(C; E; S )[9A (C = [00; 00; 00 ; 00 ; 10 ]^S = [10 ; 10]^E = [A; 10 ; A])] is a computed
symptom for the program DETECT2 (see Ex. 6 and Ex. 7).
As usual, the problem is easier to solve when we generalize: we will show that a computed
symptom is a particular case of an expected constrained atom which is not in lfp(T`;P ).
Denition 5.1
1. P is complete (resp. sucient) for the constrained atom a[c] if, for each constraint c0
such that c0 ` fcg and a[c0 ] 2 I , a[c0 ] 2 lfp(T`;P ) (resp. a[c0 ] 2 gfp(T`;P )).
2. a[c] is covered by P according to I if a[c] 2 T`;P (I ).
3. a[c] is completely covered by P according to I if, for each constraint c0 such that c0 ` fcg
and a[c0 ] 2 I , a[c0 ] is covered by P according to I .
4. A strong insuciency is a constrained atom a[c] 2 I non covered by P according to I
(i.e. a[c] 2 I T`;P (I )).
5. A weak insuciency is a constrained atom a[c] non completely covered by P according
to I (i.e. there exists c0 , c0 ` fcg and a[c0 ] is a strong insuciency).
6. a[c] is an incompleteness symptom (resp. insuciency symptom) of P according to I
if a[c] 2 I lfp(T`;P ) (resp. a[c] 2 I gfp(T`;P )).
25
The interest is that the denitions (covered/completely covered, strong/weak insuciency, insuciency/incompleteness symptom) are formulated in an uniform framework and
extend existing denitions of LP. Thus, they are better understood, particularly thanks to
proof trees and T`;P . Particular case of LP is obtained when we change constraints by substitutions and the cover by the single cover \less general". The uniform framework contributes
to the comparison between [12] and [11].
Now we can express how symptoms (insuciency symptom and incompleteness symptom)
are linked to errors (strong insuciency and weak insuciency).
Lemma 5.2
1. If a[c] is a strong insuciency then a[c] is a weak insuciency.
2. There exists a strong insuciency i there exists a weak insuciency.
3. If a[c] is an insuciency symptom then a[c] is an incompleteness symptom.
4. There exists a strong insuciency if there exists an insuciency symptom.
Proof.
1. Let a[c] be a strong insuciency, i.e. a[c] 2 I T`;P (I ).
If c0 = c then c0 ` fcg and a[c0 ] 2 I but a[c0 ] is not covered by P , thus a[c] is not
completely covered by P and a[c] is a weak insuciency.
2. ) is deduced from 1.
( Let a[c] be a weak insuciency, i.e. there exists c0 such that c0 ` fcg, a[c0 ] 2 I and
a[c0 ] is not covered by P , thus a[c0] is a strong insuciency.
3. Let a[c] be an insuciency symptom, i.e. a[c] 2 I gfp(T`;P ).
lfp(T`;P ) gfp(T`;P ), thus, a[c] is an incompleteness symptom.
4. Let us assume that there is no strong insuciency, thus I T`;P (I ).
Therefore I is a post xed point of T`;P , I gfp(T`;P ) and, consequently, there is no
insuciency symptom.
Lemma 5.2 is essential inasmuch as it expresses links between the dierent notions and
shows that if there exists a symptom then there exists an error. The particular case where
the error is the symptom establishes the correspondence strong insuciency / insuciency
symptom and weak insuciency / incompleteness symptom.
Diagnosis algorithm is used when a symptom is observed during a computation. Thus,
we show that a computed symptom is a particular case of insuciency symptom (or incompleteness symptom). This particular case corresponds to the existence of a nite SLD-tree
for the goal concerning the symptom atom.
26
Lemma 5.3 If there exists a nite SLD-tree for the goal
a with success c ; : : : ; cm then
there exists an integer k such that, for each constraint c, if a[c] 2 TP # k then c ` ; or
c 2 fc ; : : : ; cmg.
Proof. Let us assume that there exists a nite SLD-tree for the goal a. Let k0 be the
height of this SLD-tree. Each skeleton S for the goal a (rooted by a : : :), such that
the depth of the nodes of undef (S ) is > k0, is rejected.
From Lemma 4.3 and the previous remark, let c be a constraint, each partial proof tree, only
using program rules, rooted by a[c], whose hypotheses depth is > k0, is such that c ` ;.
Let c be a constraint such that a[c] is the root of a complete proof tree, only using program
rules, whose height is k0 such that, for each i = 1; : : : ; m, c 6= ci. Thus, from Lemma 4.3,
there exists a complete skeleton, whose height is k0 , for the question a whose associated
constraint is dierent of the answer constraints to the goal a. This contradicts hypotheses
on the SLD-tree for a.
Constrained atoms of TP # n exactly are the root of proof trees, only using program rules,
whose height is n and the root of partial proof trees whose undened nodes (hypothesis)
depth is n.
So, k = k0 + 1 is sucient.
1
1
Lemma 5.4 For each integer n, if a[c] 2 T`;P # n then there exists C such that c ` C and,
for each constraint c0 2 C , a[c0 ] 2 TP # n.
Proof. The lemma is proved by induction on the integer n.
1. If a[c] 2 T`;P # 0 then C = fcg is sucient.
2. Let us assume that, for each integer i n, if a[c] 2 T`;P # i then there exists C such
that c ` C and, for each constraint c0 2 C , a[c0 ] 2 TP # i.
Let a[c] 2 T`;P # n + 1, thus a[c] 2 T` (TP (T`;P # n)).
Consequently there exists C such that c ` C and, for each constraint c0 2 C , a[c0] 2
TP (T`;P # n). So, for each constraint c0 2 C , there exists a renamed clause a
cc 2 ac1 ; : : : ; acmc such that c0 = 9 a (c0c ^ c0 ^ ^ c0mc ) and, for each i = 1; : : : ; mc ,
a[c0i] 2 T`;P # n. That is, for each constraint cci , there exists Cci such that cci ` Cci
and, for each constraint c0 2 Cci , aci [c0 ] 2 TP # n.
On the one hand, the constraint c is such that c ` f9 a (cc ^ c0 ^ ^ c0mc ) j c0 2 C g.
On the other hand, for each constraint c0 2 C , for each constraint c0c1 2 Cc1 ; : : : ; c0cmc 2
Ccmc , a[9 a (cc ^ c0c1 ^ ^ c0cmc )] 2 TP # n + 1.
The CONJ and REFL properties of the cover relation guarantees that, for each
constraint c0 2 C ,
0
0
0
1
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
c0c ^ cc1 ^ ^ c0cmc ` fc0 ^ cc1 ^ ^ c0cmc j c0ci 2 Cci ; i = 1; : : : ; m0cg
0
0
0
0
0
0
0
0
0
The EXIS property of the cover relation guarantees that, for each constraint c0 2 C ,
9 a (c0c ^ cc ^ ^ c0cmc ) ` f9 a (c0 ^ cc ^ ^ c0cmc ) j c0ci 2 Cci ; i = 1; : : : ; m0cg
0
1
0
0
1
0
27
0
0
0
0
The TRAN property of the cover relation guarantees that
c ` f9 a (c0 ^ cc1 ^ ^ c0cmc ) j c0 2 C; c0ci 2 Cci ; i = 1; : : : ; m0cg
0
0
0
0
0
C = f9 a (c0 ^ cc1 ^ ^ c0cmc ) j c0 2 C; c0ci 2 Cci ; i = 1; : : : ; m0cg is sucient.
0
0
0
0
0
Lemma 5.5 If a[c] 2 T`;P # ! and there exists a nite SLD-tree for the goal a with
success c ; : : : ; cm then there exists C fc ; : : : ; cm g such that c ` C (i.e. a[c] 2 SS`(P )).
Proof. Let a[c] 2 T`;P # ! such that there exists a nite SLD-tree for a with success
1
1
c ; : : : ; cm.
Lemma 5.4 shows that, for each integer n, there exists Cn0 such that c ` Cn0 and, for each
constraint c0 2 Cn0 , a[c0] 2 TP # n.
Lemma 5.3 guarantees that there exists k such that, for each constraint c0, if a[c0] 2 TP # k
then c ` ; or there exists 1 i m such that c0 = ci.
C = Ck0 is sucient.
1
Lemma 5.6 If a[c] is a computed symptom then a[c] is an insuciency symptom.
Proof. Let a[c] be a computed symptom. If a[c] is not an insuciency symptom then
a[c] 2 gfp(T`;P ), thus a[c] 2 T`;P # ! and, from Lemma 5.5, c is covered by the answer
constraints to the question a. This is not possible because a[c] is a computed symptom.
Thus, a[c] is an insuciency symptom.
Consequently, if there exists a computed symptom then there exists a strong insuciency
and a weak insuciency (regardless of the computation rule).
It emerges from this that there exists two families of denitions concerning missing answers. The two families exists in LP and constraint introduction makes clear subtleties in
their dierences. We fully understand these dierences thanks to T`;P , because its least xed
point is equal to T` (lfp(TP )) (the two sets are proved equal to lfp(T`[;P )) and because there
is not the single cover property any more. It is interesting to note that T`;P has been selected
in the denitions, whereas it is not the most natural to dene SS` (P ). We emphasize that,
in general, gfp(T`;P ) 6= T`(gfp(TP )) 6= gfp(T`[;P ).
In LP, two algorithm families are associated to the two denition families. Algorithms
of [27, 12] (strong insuciency) provide an error notion more precise than algorithms of [11]
(weak insuciency), but oracle interaction is more complicated. Indeed, for [27, 12], oracle
answers to query by substitutions (variable instantiation) while, for [11], it just answers yes
or no.
2
2
As usual, the intended semantics interaction is formalized by the concept of oracle.
28
5.2 Diagnosis Algorithm
Now, we propose an algorithm inspired from [11]. The input is a computed symptom according to the standard strategy and the output is a weak insuciency. Thus oracle just
answers yes or no while it has to answer by constraint in an algorithm which searches a
strong insuciency.
The search forest for p(~x)[c] consists of a tree for each non-unary clause R 2 P of the
packet of p such that if p(~x) c 2 b ; : : : ; bn is a variant of R then not(c ^ 9 x c ` ;).
The tree is rooted by hb ; c ^ 9 x ci.
Let hbi; cii be a node of the tree and C = fVc 2SSbi c00 j SSbi = fc00 j bi [c00] is an answer and
not(c00 ^ ci ` ;)gg then, for each c0 2 C , hbi; cii, has a node
1
1
1
1
1
~
~
00
labeled by hbi ; c0i if i < n;
labeled by h2; c0i if i = n.
+1
We call incompleteness question for the node N labeled by hbi; cii:
\Is there exist c0 such that a[c0 ] 2 I , c0 ` fcig, not(c0 ` fc00 j hx; c00 i labels a child of N g)?"
Let a[c] be the algorithm input, we ask incompleteness question for nodes labeled by
hbi; cii (bi 6= 2) of the search forest of a[c]. If the answer is yes then the algorithm is
recursively called with bi [9 bi ci]. If the answer is no for every node then the algorithm
terminates with output a[c] which is a weak insuciency.
Remark. Incompleteness questions of our algorithm are nite because the input is a computed
symptom (i.e. the standard SLD-tree is nite).
Example 9 Insuciency diagnosis session for the program DETECT2.
Constraint are simplied by Prolog III.
Symptom: go(C; E; S )[9A(C = [00; 00; 00; 00; 10] ^ E = [A; 10; A] ^ S = [10; 10])]
Is there exist a constraint c such that go(C; E; S )[c] expected, c ` f9A(C = [00 ; 00; 00; 00; 10] ^
E = [A; 10; A] ^ S = [10; 10])g and not(c ` ;)? YES
Is there exist a constraint c such that circuit(C; E; S )[c] expected, c ` f9A(C =
[00; 00; 00; 00; 10] ^ E = [A; 10; A] ^ S = [10; 10])g and not(c ` ;)? YES
Is there exist a constraint c such that at most 1(C; X )[c] expected, c ` fC = [00; 00; 00; 00; 10] ^
X = 10g and not(c ` fC = [00; 00; 00; 00; 10] ^ X = 10g)? NO
Error: circuit(C; E; S )[9A(C = [00; 00; 00; 00; 10] ^ E = [A; 10; A] ^ S = [10; 10])]
The algorithm has isolated a denition which is responsible for the symptom. Error is due
to the denition of circuit (XOR has been coded by NOT OR).
29
6 Conclusion
We reformulate operational semantics and declarative semantics of constraint logic programs in a uniform formal framework. Thus, computed answers and declarative answers
are straightforwardly linked through an abstract cover relation. Program semantics can be
dened in reference to a model or a theory, and it can also take into account incompleteness
of constraint solvers.
The interest of this novel semantics is to study error diagnosis. We have dened insuciency symptoms and incompleteness symptoms and the two associated kinds of errors in a
uniform framework contributing to their comparison.
The diagnosis algorithm behave as an intelligent trace. It follows the straight path toward
the error and generate only relevant information. It provides a limited piece of erroneous
code (a predicate denition) which makes correction easier. The algorithm of Sect. 5.2 assume
that the symptom is computed by the standard strategy. In accordance with Lemma 5.6 and
5.2, it would be interesting to have an algorithm which does not depend on the computation
rule used to compute the symptom.
Since the two families of symptoms and errors are dened in a single framework, we
can nd algorithms in which they collaborate (to combine straightforward query and more
precise errors).
Some programs have the form: go(~x) big constraint 2 . Then, we observe an incompleteness symptom go(~x)[c] and we call our diagnosis algorithm which provide the error
go(~x)[c]. It is not very interesting! We can discuss the programming methodology and prefer a better structured program: in general, it is more straightforward to cut a problem in
easier subproblem: : : but it is not the matter. Debugging the big constraint has no mean
in our framework: constraint predicates are assumed to be correct. Concerning this program, there exists a symptom because the programmer has made an error when he wrote
the big constraint. It is certainly possible to say more than go(~x)[c] is an error. The aim is
to elaborate appropriate formal ways based on a semantics of the variables of the constraint.
More and more CLP systems, for practical purpose, use approximations of the possible
domain values of the variables. Approximations contains all the answers but eventually
other values (i.e. the answer constraint is covered by the approximation). They are, for
example, intervals on continuous domain (CLP(BNR), Prolog IV) or (nite) discrete domain
(CLP(FD), CHIP). Works in progress consist in taking into account approximations in
our framework. Approximations have similar properties to cover relations. We could take
advantage of the analogies in dening new symptom and error notions.
30
References
[1] Peter Aczel. An Introduction to Inductive Denitions, chapter 7, pages 739{782. In J.
Barwise, editor, Handbook of Mathematical Logic. North-Holland Publishing Company,
1977.
[2] Frederic Benhamou. Boolean Algorithms in Prolog III. In Alain Colmerauer and
Frederic Benhamou, editors, Constraint Logic Programming: Selected Research, chapter 17, pages 307{326. MIT Press, 1993.
[3] Michel Bergere. Approche declarative du diagnostic d'erreur pour la programmation en
logique avec negation. PhD thesis, Universite d'Orleans, 1991.
[4] Michel Bergere, Gerard Ferrand, Francois Le Berre, Bernard Malfon, and Alexandre
Tessier. La Programmation Logique avec Contraintes revisitee en termes d'arbres de
preuve et de squelettes. Technical Report 95/06, LIFO, University of Orleans, 1995.
[5] Philippe Codognet. Programmation logique avec contraintes : une introduction. In
Journees Francophones de Programmation en Logique, volume 14 of Technique et Science Informatique, pages 665{692. Hermes, 1995.
[6] Alain Colmerauer. An Introduction to Prolog III. Communications of the ACM,
33(7):69{90, 1990.
[7] Marco Comini, Giorgio Levi, and Giuliana Vitiello. Abstract Debugging of Logic Programs. In Laurent Fribourg and F. Turini, editors, Logic Program Synthesis and Transformation and Metaprogramming, volume 883 of Lecture Notes in Computer Science,
pages 440{450. Springer-Verlag, 1994.
[8] Marco Comini, Giorgio Levi, and Giuliana Vitiello. Declarative Diagnosis Revisited. In
John Lloyd, editor, International Logic Programming Symposium, Logic Programming,
pages 275{287. MIT Press, 1995.
[9] Marco Comini, Giorgio Levi, and Giuliana Vitiello. Ecient Detection of Incompleteness Errors in the Abstract Debugging of Logic Programs. In Mirelle Ducasse, editor,
Automated and Algorithmic Debugging, pages 159{174. IRISA-CNRS, 1995.
[10] Pierre Deransart and Jan Maluszynski. A Grammatical View of Logic Programming.
MIT Press, 1993.
[11] Wlodek Drabent, Simin Nadjm-Tehrani, and Jan Maluszynski. Algorithmic Debugging
with Assertions. In Harvey Abramson and M. H. Rogers, editors, Meta-Programming
in Logic Programming, pages 501{522. MIT Press, 1989.
[12] Gerard Ferrand. Error Diagnosis in Logic Programming: an adaptation of E. Y.
Shapiro's method. Journal of Logic Programming, 4:177{198, 1987.
31
[13] Gerard Ferrand. The Notions of Symptom and Error in Declarative Diagnosis of Logic
Programs. In Automated and Algorithmic Debugging, volume 749 of Lecture Notes in
Computer Science, pages 40{57. Springer-Verlag, 1993.
[14] Maurizio Gabbrielli and Giorgio Levi. Modeling answer constraints in Constraint Logic
Programs. In Vijay A. Saraswat and K. Ueda, editors, International Conference on
Logic Programming, pages 238{252. MIT Press, 1991.
[15] Roberto Giacobazzi, Saumya K. Debray, and Giorgio Levi. A Generalized Semantics for
Constraint Logic Programs. In International Conference on Fifth Generation Computer
Systems, pages 581{591, 1992.
[16] Roberto Giacobazzi, Saumya K. Debray, and Giorgio Levi. Generalized Semantics and
Abstract Interpretation for Constraint Logic Programs. Journal of Logic Programming,
25(3):191{248, 1995.
[17] Nevin C. Heintze, Joxan Jaar, Spiro Michaylov, Peter J. Stuckey, and Roland H.C. Yap.
The CLP(R) Programmer's Manual Version 1.2. IBM Thomas J. Watson Research
Center, 1992.
[18] Joxan Jaar and Jean-Louis Lassez. Constraint Logic Programming. In 14th ACM
Symposium on Principles of Programming Languages, pages 111{119. ACM, 1987.
[19] Joxan Jaar and Michael J. Maher. Constraint Logic Programming: a survey. Journal
of Logic Programming, 19-20:503{581, 1994.
[20] Francois Le Berre and Alexandre Tessier. Declarative Incorrectness Diagnosis in Constraint Logic Programming. In Joint Conference on Declarative Programming, 1996.
[21] John W. Lloyd. Declarative Error Diagnosis. New Generation Computing, 5:133{154,,
1987.
[22] John W. Lloyd. Foundations of Logic Programming. Springer-Verlag, second edition,
1987.
[23] Michael J. Maher. A Logic Programming view of CLP. In Warren, editor, International
Conference on Logic Programming, pages 737{753. MIT Press, 1993.
[24] Simin Nadjm-Tehrani. Contributions to the Declarative Approach to Debugging Prolog
Programs. PhD thesis, Linkoping University, 1989.
[25] Vijay A. Saraswat. The Category of Constraint Systems is Cartesian-Closed. In Logic
In Computer Science. IEEE Press, 1992.
[26] Vijay A. Saraswat, Martin Rinard, and Prakash Panangaden. Semantic foundations
of concurrent constraint programming. In Symposium on Principles of Programming
Languages, pages 333{352. ACM Press, 1991.
32
[27] Ehud Y. Shapiro. Algorithmic Program Debugging. ACM Distinguished Dissertation.
MIT Press, 1982.
[28] Pascal Van Hentenryck. Constraint Satisfaction in Logic Programming. Logic Programming. MIT Press, 1989.
[29] Pascal Van Hentenryck. Constraint Logic Programming. Knowledge Engineering Review, 6(3):151{194, 1991.
33
Download