1% BEGIN LICENSE BLOCK
2% Version: CMPL 1.1
3%
4% The contents of this file are subject to the Cisco-style Mozilla Public
5% License Version 1.1 (the "License"); you may not use this file except
6% in compliance with the License.  You may obtain a copy of the License
7% at www.eclipse-clp.org/license.
8% 
9% Software distributed under the License is distributed on an "AS IS"
10% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
11% the License for the specific language governing rights and limitations
12% under the License. 
13% 
14% The Original Code is  The ECLiPSe Constraint Logic Programming System. 
15% The Initial Developer of the Original Code is  Cisco Systems, Inc. 
16% Portions created by the Initial Developer are
17% Copyright (C) 1996 - 2006 Cisco Systems, Inc.  All Rights Reserved.
18% 
19% Contributor(s): Carmen Gervet, ECRC
20% 
21% END LICENSE BLOCK
22
23%
24% @(#)extconjunto.tex	1.7 96/09/30 
25%
26% Author:        Carmen Gervet
27%
28\chapter{ The Set Domain Library}
29\label{chapconjunto}
30\index{library!conjunto.pl|(}
31
32{\bf Note: As of \eclipse\ release 5.1, the library described
33in this chapter is being phased out and replaced by the new set solver
34library lib(ic\_sets). See the corresponding chapters in the
35{\em Library Manual} and the
36\biptxtref{Reference Manual}{fd_sets:_/_}{../bips/lib/fd_sets/index.html}
37for details.}
38\vspace{3mm}
39
40{\em\bf Conjunto} is a system to solve set constraints over finite set
41domain terms. It has been developed using the kernel of \eclipse\ based
42on metaterms. It contains the finite domain library of \eclipse.  The
43library {\bf conjunto.pl} implements constraints over set domain terms
44that contain herbrand terms as well as ground sets. Modules that use
45the library must start with the directive
46\begin{quote}\begin{verbatim}
47:- use_module(library(conjunto))
48\end{verbatim}\end{quote}
49For those who are already familiar with the \eclipse\ constraint library manual
50this manual follows the finite domain library structure.
51
52For further information about this library,
53please email to c.gervet@icparc.ic.ac.uk.
54
55\section{Terminology}
56The computation domain of {\em\bf Conjunto} is finite so set
57domain and set term will stand respectively for finite set domain and
58finite set term in the following. Here are defined some of the terms
59mainly used in the predicate description.
60
61\noindent
62{\bf Ground set}
63\begin{quote} A known finite set containing only atoms from
64the Herbrand Universe or its powerset but without any variable.
65\end{quote}
66\index{ground set}
67{\bf Set domain}
68\begin{quote}
69A discrete lattice or powerset {\em D} attached to a set
70variable {\em S}. {\em D} is defined by
71{$\{S \in 2^{lub_s} \mid glb_s \subseteq S\}$}
72under inclusion specified by the notation $Glb_s .. Lub_s$.
73$Glb_s$ and $Lub_s$
74represent respectively the intersection and union
75of elements of D.  Thus they are both ground sets. S is then called a
76{\bf set domain variable}.
77\end{quote}
78\index{set domain}
79{\bf Weighted set domain}
80\begin{quote} A specific set domain {\em WD} attached to
81a set variable {\em S} where each element of {\em WD} is of the
82form {\em e(s,w)}. {\em s} is a ground set representing a possible value of the
83set variable and {\em w} is the weight or cost associated to this
84value. e.g.
85\begin{quote}\begin{verbatim}
86WD = {e(1,50),e({1,3},20)}..{e(1,50),e({1,3},20),e(f(a),100)}.
87\end{verbatim}\end{quote}
88D would have been:
89\begin{quote}\begin{verbatim}
90{1,{1,3}}..{1,{1,3},f(a)}.
91\end{verbatim}\end{quote}
92\end{quote}
93\index{weighted set}
94{\bf Set expression}
95\begin{quote} A composition of set domain variables or ground sets together
96with set operator symbols which are the standard ones coming from set
97theory.
98
99$S ::= S_1 \cap S_2 \mid S_1 \cup S_2 \mid S_1 \setminus S_2$
100
101\end{quote}
102\index{set expression}
103{\bf Set term}
104\begin{quote} Any term of the followings: (1) a ground set, (2) a
105set domain  variable or (3)  a set expression. All set built-in
106predicates deal with set terms thus with any of the three cases.
107\end{quote}
108\index{set term}
109\section{Syntax}
110
111\begin{itemize}
112\item A ground set is written using the characters \verb!{! and \verb!}!, e.g.
113\verb!S = {1,3,{a,g}, f(2)}!
114
115\item A domain D attached to a set variable is specified by two ground
116sets : $Glb_s .. Lub_s $
117
118\item Set expressions:
119Unfortunately the characters representing the usual set operators are
120not available on our monitors so we use a specific syntax making the
121connection with arithmetic operators: 
122\index{\andsy}
123\index{\orsy}
124\index{\bsl}
125\begin{itemize}
126\item $\cup$ is represented by \orsy
127\item $\cap$ is represented by \andsy
128\item $\setminus$ is represented by \bsl
129\end{itemize}
130\end{itemize}
131
132\section{The solver}
133The {\em\bf Conjunto} solver acts in a data driven way using a
134relation between {\em states}. The transformation performs interval
135reduction over the set domain bounds. The set expression domains are
136approximated in terms of the domains of the set variables involved.
137From a constraint propagation viewpoint this means that constraints
138over set expressions can be approximated in terms of constraints over
139set variables. A failure is detected in the constraint propagation
140phase as soon as one domain lower bound $glb_s$ is not included in its
141associated upper bound $lub_s$. Once a solved form has been reached
142all the constraints which are not definitely solved are delayed and
143attached to the concerned set variables.
144\index{set domain}
145\section{Constraint predicates}
146
147\index{ground set}
148\index{set variable}
149
150{\bf ?Svar \verb/`::/ ++Glb..++Lub} 
151\begin{quote}
152attaches a domain to the set variable or to a list of set variables
153{\em Svar}.
154If
155$Glb \not\subseteq Lub$
156it fails. If {\em Svar} is already a domain
157variable its domain will be updated according to the new domain; if
158{\em Svar} is instantiated it fails. Otherwise if {\em Svar} is free it
159becomes a set variable.
160\end{quote}
161\index{set domain}
162{\bf set(?Term)} 
163\begin{quote}
164succeeds if {\em Term} is a ground set.
165\end{quote}
166\index{ground set}
167{\bf ?S \verb/`=/ ?S1} 
168\begin{quote}
169The value of the set term {\em S} is equal to
170the value of the set term {\em S1}.
171\end{quote}
172\index{`=/2}
173{\bf ?E in ?S} 
174\begin{quote}
175The element {\em E} is an element of {\em S}.  If {\em E} is ground it
176is added to the lower bound of the domain of {\em S}, otherwise the constraint is
177delayed. If {\em E} is ground and does not belong to the upper bound
178of {\em S} domain, it fails.
179\end{quote}
180\index{in/2}
181{\bf ?E notin ?S}
182\index{notin/2}
183\begin{quote}
184The element {\em E} does not belong to {\em S}. If {\em E} is ground
185it is removed from the upper bound of {\em S}, otherwise the
186constraint is delayed. If {\em E} is ground and belongs to the upper
187bound of the domain of {\em S}, it is removed from the upper bound and
188the constraint is solved. If {\em E} is ground and belongs to the
189lower bound of {\em S} domain, it fails.
190\end{quote}
191{\bf ?S \verb/`</ ?S1} 
192\index{\verb/`<//2}
193\begin{quote}
194The value of the set term {\em S} is a subset of the value of the set
195term {\bf S1}. If the two terms are ground sets it just checks the
196inclusion and succeeds or fails. If the lower bound of the domain of {\em
197S} is not included in the upper bound of {\em S1} domain, it fails.
198Otherwise it checks the inclusion over the bounds. The constraint is
199then delayed.
200\end{quote}
201{\bf ?S \verb/`<>/ ?S1}
202\index{\verb/`<>//2}
203\begin{quote}
204The domains of S and S1 are disjoint (intersection empty).
205\end{quote}
206{\bf all\verb/_/union(?Lsets, ?S)}
207\index{all\verb/_/union/2}
208\begin{quote}
209{\em Lsets} is a list of set variables or ground sets. {\em S} is a
210set term which is the union of all these sets. If {\em S} is a free
211variable, it becomes a set variable and its attached domain is defined
212from the union of the domains or ground sets in {\em Lsets}.
213\end{quote}
214{\bf all\verb/_/disjoint(?Lsets)}
215\index{all\verb/_/disjoint/2}
216\begin{quote}
217{\em Lsets} is a list of set variables of ground sets. All the sets are pairwise
218disjoint.
219\end{quote}
220{\bf \verb/#/(?S,?C)} 
221\index{\#/2}
222\begin{quote}
223{\em S} is a set term and {\em C} its cardinality. C can be a free
224variable, a finite domain variable or an integer. If C is free, this
225predicate is a mean to access the set cardinality and attach it to C.
226If not, the cardinality of S is constrained to be C.
227\end{quote}
228{\bf sum\verb/_/weight(?S,?W)}
229\index{sum\verb/_/weight/2}
230\begin{quote}
231{\em S} is a set variable whose domain is a {\em weighted domain}.
232{\em W} is the weight of {\em S}. If {\em W} is a free variable, this
233predicate is a mean to access the set weight and attach it to W. If
234not, the weight of S is constrained to be W. e.g.
235\begin{verbatim}
236S `:: {e(2,3)}..{e(2,3), e(1,4)}, sum_weight(S, W)
237\end{verbatim}
238returns W :: 3..7.
239\end{quote}
240{\bf refine(?Svar)} 
241\index{refine/1}
242\begin{quote}
243If {\em Svar} is a set variable, it labels {\em Svar} to its first
244possible domain value. If there are several instances of {\em Svar},
245it creates choice points. If {\em Svar} is a ground set, nothing happens.
246Otherwise it fails. 
247\end{quote}
248
249\section{Examples}
250
251\subsection{Set domains and interval reasoning}
252First we give a very simple example to demonstrate the expressiveness
253of set constraints and the propagation mechanism.
254
255\begin{quote}\begin{verbatim}
256:- use_module(library(conjunto)).
257
258[eclipse 2]: Car `:: {renault} .. {renault, bmw, mercedes, peugeot},
259    Type_french = {renault, peugeot} , Choice `= Car /\ Type_french.
260
261Choice = Choice{{renault} .. {peugeot, renault}}
262Car = Car{{renault} .. {bmw, mercedes, peugeot, renault}}
263Type_french = {peugeot, renault}
264
265Delayed goals:
266      inter_s({peugeot, renault}, Car{{renault}..{bmw, mercedes,
267          peugeot, renault}}, Choice{{renault} .. {peugeot, renault}})
268yes.
269\end{verbatim}\end{quote}
270If now we add one cardinality constraint:
271\begin{quote}\begin{verbatim}
272[eclipse 3]: Car `:: {renault} .. {renault, bmw, mercedes, peugeot},
273    Type_french = {renault, peugeot} , Choice `= Car /\ Type_french,
274    #(Choice, 2).
275
276Car = Car{{peugeot, renault} .. {bmw, mercedes, peugeot, renault}}
277Type_french = {peugeot, renault}
278Choice = {peugeot, renault}
279yes.
280\end{verbatim}\end{quote}
281The first example gives a set of cars from which we know
282\verb/renault/ belongs to. The other labels
283\verb/{renault, bmw, mercedes, peugeot}/ are possible elements of this set. The
284\verb/Type_french/ set is ground and
285\verb/Choice/ is the set term resulting from the intersection of the
286first two sets. The first execution tells us that 
287\verb/renault/ is element of \verb/Choice/ and \verb/peugeot/ might be
288one. The intersection constraint is partially satisfied and might be
289reconsidered if one of the domain of the set terms involved changes.
290The cosntraint is  delayed.
291
292In the second example an additional constraint restricts the cardinality of
293\verb/Choice/ to 2. Satisfying this constraint implies setting the
294\verb/Choice/ set to \verb/{peugeot, renault}/. The domain of this
295set has been modified so is the intersection constraint activated and
296solved again. The final result adds \verb/peugeot/ to the \verb/Car/
297set variable. The intersection constraint is now satisfied and removed
298from the constraint store.
299
300\subsection{Subset-sum computation with convergent weight}
301
302A more elaborate example is a small decision problem. We are given a
303finite weighted set and a {\em target} $t \in N$. We ask whether there
304is a subset $s'$ of {\em S} whose weight is {\em t}. This also corresponds to
305having a single weighted set domain and to look for its value such that
306its  weight is {\em t}. 
307
308This problem is NP-complete. It is approximated in Integer Programming
309using a procedure which "trims" a list according to a given parameter.
310For example, the set variable
311\begin{quote}\begin{verbatim}
312S `:: {}..{e(a,104), e(b,102), e(c,201) ,e(d,101)}
313\end{verbatim}\end{quote}
314is approximated by the set variable
315\begin{quote}\begin{verbatim}
316S' `:: {}..{e(c,201) ,e(d, 101)}
317\end{verbatim}\end{quote}
318if the parameter
319delta is 0.04 ($0.04 = 0.2 \div n$ where $n = \# S$).
320\begin{verbatim}
321:- use_module(library(conjunto)).
322
323% Find the optimal solution to the subset-sum problem
324solve(S1, Sum) :-
325        getset(S),
326        S1 `:: {}.. S,
327        trim(S, S1),
328        constrain_weight(S1, Sum),
329        sum_weight(S1, W),
330        Cost = Sum - W,
331        min_max(labeling(S1), Cost).
332
333% The set weight has to be less than Sum
334constrain_weight(S1, Sum) :-
335        sum_weight(S1, W),
336        W #<= Sum.
337
338% Get rid of a set of elements of the set according to a given delta
339trim(S, S1) :-
340        set2list(S, LS),
341        trim1(LS, S1).
342        
343trim1(LS, S1) :-
344        sort(2, =<, LS, [E | LSorted]), 
345        getdelta(D),
346        testsubsumed(D, E, LSorted, S1).
347
348testsubsumed(_, _, [], _).
349testsubsumed(D, E, [F | LS], S1) :-
350        el_weight(E, We),
351        el_weight(F, Wf),
352        ( We =< (1 - D) * Wf ->
353            testsubsumed(D, F, LS, S1)
354        ;
355            F notin S1,
356            testsubsumed(D, E, LS, S1)
357        ).
358
359% Instantiation procedure
360labeling(Sub) :-
361        set(Sub),!.
362labeling(Sub) :-
363        max_weight(Sub, X),
364        ( X in Sub ; X notin Sub ),
365        labeling(Sub).
366
367% Some sample data
368getset(S) :- S = {e(a,104), e(b,102), e(c,201), e(d,101), e(e,305),
369                e(f,50), e(g,70),e(h,102)}.
370getdelta(0.05).
371\end{verbatim}
372
373The approach is is the following: first create the set domain
374variable(s), here there is only one which is the set we want to find.
375We state constraints which limit the weight of the set. We apply the
376``trim'' heuristics which removes possible elements of the set domain.
377And finally we define the cost term as a finite domain used in the
378{\bf min\verb/_/max/2} predicate. The cost term is an integer. The
379{\bf conjunto.pl} library makes sure that any modification of an fd
380term involved with a set term is propagated on the set domain. The
381labeling procedure refines a set domain by selecting the element of
382the set domain which has the biggest weight using
383\verb/max_weight(Sub, X),/ and by adding it to the lower bound of the set
384domain. When running the example, we get the following result:
385\begin{quote}\begin{verbatim}
386[eclipse 3]: solve(S, 550).
387Found a solution with cost 44
388Found a solution with cost 24
389
390S = {e(d, 101), e(e, 305), e(f, 50), e(g, 70)}
391yes.
392\end{verbatim}\end{quote}
393An interesting point is that in set based problems, the optimization
394criteria mainly concern the cardinality or the weight of a set term.
395So in practice we just need to label the set term while applying the
396{\bf fd} optimization predicates upon the set cardinality or the set
397weight. There is no need to define additional optimization predicates.
398
399\subsection{The ternary Steiner system of order n}
400A ternary Steiner system of order {\em n} is a set of 
401$n * (n-1) \setminus 6$
402triplets of distinct elements taking their values between {\em 1} and
403{\em n}, such that all the pairs included in two different triplets are
404different. 
405
406This problem is very well dedicated to be solved using set
407constraints:  (i) no order is required in the triplet
408elements and (ii) the constraint of the problem can be easily written
409with set constraints saying that any intersection of two set terms
410contains at most one element. With a finite domain approach,  the list of 
411domain variables which should be distinct requires to be given
412explicitely, thus the problem modelling is would be bit ad-hoc and not valid
413for any {\em n}.
414
415\begin{verbatim}
416:- use_module(library(conjunto)).
417
418% Gives one solution to the ternary steiner problem.
419% n has to be congruent to 1 or 3 modulo 6.
420
421steiner(N, LS) :-
422        make_nbsets(N,NB),
423        make_domain(N, Domain),
424        init_sets(NB, Domain, LS),
425        card_all(LS, 3),
426        labeling(LS, []).
427
428labeling([], _).
429labeling([S | LS], L) :-
430        refine(S),
431        (LS = []  ; LS = [L2 | _Rest],
432        all_distincts([S | L], L2),
433        labeling(LS, [S | L])).
434
435% the labeled sets are distinct from the set to be labeled
436% this constraint is a disjonction so it is useless to put it
437% before the labeling as no information would be deduced anyway
438all_distincts([], _).
439all_distincts([S1 |L], L2) :-
440        distinctsfrom(S1, L2),
441        all_distincts(L, L2).
442
443distinctsfrom(S, S1) :-
444        #(S /\ S1,C),
445        fd:(C #<= 1).
446
447% creates the required number of set variables according to n
448make_nbsets(N,NB) :-
449        NB is N * (N-1) // 6.
450
451% initializes the domain of the variables according to n
452make_domain(N, Domain) :-
453        D :: 1.. N,
454        dom(D, L),
455        list2set(L, Domain).
456
457init_sets(0, _Domain, []) :- !.
458init_sets(NB, Domain, Sol) :-
459        NB1 is NB-1,
460        init_sets(NB1, Domain, Sol1),
461        S `:: {} .. Domain,
462        Sol = [S | Sol1].
463
464% constrains the cardinality of each set variable to be equal to V (=3)
465card_all([], _V).
466card_all([Set1|LSets], V) :-
467        #(Set1, V),
468        card_all(LSets, V).
469\end{verbatim}
470
471The approach with sets is the following: first we create the number of
472set variables required according to the initial problem definition
473such that each set variable is a triplet. Then to initialize the
474domain of these set variables we use the fd predicates which allow to
475define a domain by an implicit enumeration approach 1..n. This process
476is cleaner than enumerating a list of integer between 1 and n. Once
477all the domain variables are created, we constrain their cardinality
478to be equal to three. Then starts the labeling procedure where all the
479sets are labeled one after the other. Each time one set is labeled,
480constraints are stated between the labeled set and the next one to be
481labeled. This constraint states that two sets have at most one element
482in common. The semantics of
483$\#(S \cap S_1 ,C), C \leq 1$
484is equivalent
485to a disjunction between set values. This implies that in the
486contraint propagation phase, no information can be deduced until one
487of the set is ground and some element has been added to the second
488one. No additional heuristics or tricks have been added to this simple
489example so it works well for n = 7, 9 but with the value 13 it becomes
490quite long.  When running the example, we get the following result:
491
492\begin{verbatim}
493[eclipse 4]: steiner(7, S).
4946 backtracks
4950.75
496S = [{1, 2, 3}, {1, 4, 5}, {1, 6, 7}, {2, 4, 6}, {2, 5, 7}, {3, 4, 7}, {3, 5, 6}]   
497yes.
498\end{verbatim}
499
500
501\section{When to use Set Variables and Constraints...}
502\index{set variable}
503The {\em subset-sum} example shows that the general principle of solving
504problems using set domain constraints works just like finite domains:
505\begin{itemize}
506\item Stating the variables and assigning an initial set domain to
507them.
508\item Constraining the variables. In the above example the constraint
509is just a built-in constraint but usually one needs to define
510additional constraints.
511\item Labeling the variables, {\em i.e.}, assigning values to them.
512In the set case it would not be very efficient to select one value for
513a set variable for the size of a set domain is exponential in the
514upper bound cardinality and thus the number of backtracks could be
515exponential too. A second reason is that no specific information can
516be deduced from a failure (backtrack) whereas if (like in the refine
517predicate) we add one by one elements to the set till it becomes
518ground or some failure is detected, we benefit much more from the
519constraint propagation mechanism.  Every domain modification activates
520some constraints associated to the variable (depending on the modified
521bound) and modifications are propagated to the other variables
522involved in the constraints. The search space is then reduced and
523either the goal succeeds or it fails.  In case of failure the labeling
524procedure backtracks and removes the last element added to the set
525variable and tries to instanciate the variable by adding another
526element to its lower bound.  In the \verb/subset-sum/ example the
527labeling only concerns a single set, but it can deal with a list of
528set terms like in the \verb/steiner/ example.  Although the choice for the
529element to be added can be done without specific criterion like in the
530\verb/steiner/ example, some  user defined heuristics can be embedded
531in the labeling procedure like in the \verb/subset-sum/ example. Then
532the user needs to define his own \verb/refine/ procedure.
533\end{itemize}
534
535Set constraints propose a new modelling of already solved problems or
536allows (like for the {\em subset-sum} example) to solve new problems
537using CLP. Therefore, one should take into account the problem
538semantics in order to define the initial search space as small as
539possible and to make a powerful use of set constraints. The objective
540of this library is to bring CLP to bear on graph-theorical problems
541like the {\em steiner} problem which is a hypergraph computation
542problem, thus leading to a better specification and solving of
543problems as, packing and partitioning which find their application in
544many real life problems.  A partial list includes: railroad crew
545scheduling, truck deliveries, airline crew scheduling, tanker-routing,
546information retrieval,time tabling problems, location problems,
547assembly line balancing, political districting,etc.
548
549Sets seem adequate for problems where one is not interested in each
550element as a specific individual but in a collection of elements where
551no specific distinction is made and thus where symmetries among the
552element values need to be avoided (eg. steiner problem). They are also
553useful when heterogeneous constraints are involved in the problem like
554weight constraints combined with some disjointness constraints.
555\section{User-defined constraints}
556
557To define constraints based on set domains one needs to
558access the properties of a set term like its domain, its cardinality,
559its possible weight. As the set variable is a metaterm i.e. an
560abstract data structure, some built-in predicates allow the user to
561process the set variables and their domains, modify them and write new
562constraint predicates. 
563
564\subsection{The abstract set data structure}
565\index{metaterm}
566A set domain variable is a metaterm. The {\bf conjunto.pl} library
567defines a metaterm attribute
568
569{\bf set\{setdom:[Glb,Lub], card:C, weight:W, del\verb/_/inst:Dinst,
570del\verb/_/glb:Dglb, del\verb/_/lub:Dlub, del\verb/_/any:Dany\}}
571
572This attribute stores information regarding the set domain, its
573cardinality, and weight (null if undefined) and together with four
574suspension lists. The attribute arguments have the following meaning:
575
576\begin{itemize}
577\item {\bf setdom} The representation of the domain itself. As set
578domains are treated as abstract data types, the users should not
579access them directly, but only using built-in access and modification
580predicates presented hereafter.
581\item {\bf card} The representation of the set cardinality. The
582cardinality is initialized as soon as a set domain is attached to
583a set variable. It is either a finite domain or an integer. It can
584be accessed and modified in the same way as set domains (using
585specific built-in predicates).
586\item {\bf weight} The representation of the set weight. The weight is
587intialized to zero if the domain is not a weighted set domain, otherwise it
588is computed as soon as a weighted set domain is attached to a set
589variable. it can be accessed and modified in the same way as set
590domains (using specific built-in predicates).
591\item {\bf del\verb/_/inst} A suspension list that should be woken
592when the domain is reduced to a single set value.
593\item {\bf del\verb/_/glb} A suspension list that should be woken when
594the lower bound of the set domain is updated.
595\item {\bf del\verb/_/lub} a suspension list that should be woken when
596the upper bound of the set domain is updated.
597\item {\bf del\verb/_/any} a suspension list that should be woken when
598any reduction of the domain is inferred.
599\end{itemize}
600
601\noindent
602The attribute of a set domain variable can be accessed with the
603predicate {\bf svar\verb/_/attribute/2} or by unification
604in a matching clause:
605\index{svar\verb/_/attribute/2}
606\begin{quote}\begin{verbatim}
607get_attribute(_{set: Attr}, A) :- -?-> nonvar(Attr), Attr = A.
608\end{verbatim}\end{quote}
609The attribute arguments can be accessed by macros from the \eclipse
610{\bf structures.pl} library, if e.g. {\bf Attr} is the attribute of a
611set domain variable, the del\verb/_/inst list can be obtained by:
612\begin{quote}\begin{verbatim}
613arg(del_inst of set, Attr, Dinst)
614\end{verbatim}\end{quote}
615or by using a unification: 
616\begin{quote}\begin{verbatim}
617Attr = set{del_inst: Dinst}
618\end{verbatim}\end{quote}
619\index{unification}
620
621\subsection{Set Domain access}
622The domains are represented as abstract data types, and the users are
623not supposed to access them directly. So we provide a number of
624predicates to allow operations on set domains.
625
626\noindent
627\index{set domain}
628{\bf set\verb/_/range(?Svar,?Glb,?Lub)} 
629\index{set\verb/_/range/3}
630\begin{quote}
631If {\em Svar} is a set domain variable, it returns the lower and upper
632bounds of its domain.  Otherwise it fails.
633\end{quote}
634{\bf glb(?Svar,?Glb)} 
635\index{glb/2}
636\begin{quote}
637If {\em Svar} is a set domain variable, it returns the lower bound of
638its domain. Otherwise it fails.
639\end{quote}
640{\bf lub(?Svar, ?Lub)}
641\index{lub/2}
642\begin{quote}
643If {\em Svar} is a set domain variable, it returns the upper bound of
644its domain. Otherwise it fails.
645\end{quote}
646{\bf el\verb/_/weight(++E, ?We)}
647\index{el\verb/_/weight/2}
648\begin{quote}
649If {\em E} is element of a weighted domain, it returns the weight
650associated to {\em E}. Otherwise it fails.
651\end{quote}
652{\bf max\verb/_/weight(?Svar,?E)}
653\index{max\verb/_/weight/2}
654\begin{quote}
655If {\em Svar} is a set variable, it returns the element of its domain
656which belongs to the set resulting from the difference of the upper
657bound and the lower bound and which has the greatest weight. If {\em
658Svar} is a ground set, it returns the element with the biggest weight.
659Otherwise it fails.
660\end{quote}
661
662\noindent
663Two specific predicates make a link between a ground set and a list.
664
665\noindent
666{\bf set2list(++S, ?L)} 
667\index{set2list/2}
668\begin{quote}
669If {\em S} is a ground set, it returns the corresponding list. If {\em
670L} is also ground it checks if it is the corresponding list. If not,
671or if {\em S} is not ground, it fails.
672\end{quote}
673{\bf list2set(++L, ?S)}
674\index{list2set/2}
675\begin{quote}
676If {\em L} is a ground list, it returns the corresponding set. If {\em
677S} is also ground it checks if it is the corresponding set. If not,
678or if {\em L} is not ground, it fails.
679\end{quote}
680
681\subsection{Set variable modification}
682A specific predicate operate on the set domain {\em variables}.
683\index{set variable}
684When a set domain is reduced, some suspension lists have to be
685scheduled and woken depending on the bound modified. 
686\index{suspension list}
687
688{\bf NOTE}: Their are 4 suspension lists in the {\bf conjunto.pl}
689library, which are woken precisely when the event associated with each
690list occurs. For example, if the lower bound of a set variable is modified, two
691suspension lists will be woken: the one associated to a {\bf glb}
692modification and the one associated to {\bf any} modification. This
693allows user-defined constraints to be handled efficiently. 
694
695\noindent
696{\bf modify\verb/_/bound(Ind, ?S, ++Newbound)}
697\index{modify\verb/_/bound/3}
698\begin{quote}
699{\em Ind} is a flag which should take the value {\bf lub} or {\bf glb},
700otherwise it fails ! If {\em S} is a ground set, it succeeds if we
701have {\em Newbound} equal to S. If {\em S} is a set variable, its new
702lower or upper bound will be updated. For monotonicity reasons,
703domains can only get reduced. So a new upper bound has to be contained
704in the old one and a new lower bound has to contain the old one.
705Otherwise it fails.
706\end{quote}
707
708\section{Example of defining a new constraint}
709
710The following example demonstrates how to create a new set constraint. To
711show that set inclusion is not restricted to ground herbrand terms we
712can take the following constraint which defines lattice inclusion over
713lattice domains:
714\begin{quote}\begin{verbatim}
715S_1 incl S
716\end{verbatim}\end{quote}
717Assuming that {\em S} and $S_1$ are specific set variables of the form
718\begin{quote}\begin{verbatim}
719S `:: {} ..{{a,b,c},{d,e,f}}, ..., S_1 `:: {} ..{{c},{d,f},{g,f}}
720\end{verbatim}\end{quote}
721we would like to define such a predicate
722that will be woken as soon as one or both set variables' domains are
723updated in such a way that would require updating the other variable's
724domain by propagating the constraint. This constraint definition also
725shows that if one wants to iterate over a ground set (set of known
726elements) the transformation to a list is convenient. In fact
727iterations do not suit sets and benefit much more from a list
728structure. We define the predicate \verb/incl(S,S1)/ which corresponds
729to this constraint:
730
731\begin{verbatim}
732:- use_module(library(conjunto)).
733incl(S,S1) :-
734          set(S),set(S1),
735          !,
736          check_incl(S, S1).
737incl(S, S1) :-
738          set(S),
739          set_range(S1, Glb1, Lub1),
740          !,
741          check_incl(S, Lub1),
742          S + Glb1 `= S1NewGlb,
743          modify_bound(glb, S1, S1NewGlb).
744incl(S, S1) :-
745          set(S1),
746          set_range(S, Glb, Lub),
747          !,
748          check_incl(Glb, S1),
749          large_inter(S1, Lub, SNewLub),
750          modify_bound(lub, S, SNewLub).
751incl(S,S1) :-
752          set_range(S, Glb, Lub),
753          set_range(S1, Glb1, Lub1),
754          check_incl(Glb, Lub1),
755          Glb \/ Glb1 `= S1NewGlb,
756          large_inter(Lub, Lub1, SNewLub),
757          modify_bound(glb, S1, S1NewGlb),
758          modify_bound(lub, S, SNewLub),
759          ( (set(S) ; set(S1)) ->
760               true
761         ;
762               make_suspension(incl(S, S1),2, Susp),
763               insert_suspension([S,S1], Susp, del_any of set, set)
764          ),
765          wake.
766
767large_inter(Lub, Lub1, NewLub) :-
768          set2list(Lub, Llub),
769          set2list(Lub1, Llub1),
770          largeinter(Llub, Llub1, LNewLub),
771          list2set(LNewLub, NewLub).
772
773largeinter([], _, []).
774largeinter([S | List_set], Lub1, Snew) :-
775          largeinter(List_set, Lub1, Snew1),
776          ( contained(S, Lub1) ->
777                Snew = [S | Snew1]
778          ;
779                Snew = Snew1
780          ).
781
782check_incl({}, _S) :-!.
783check_incl(Glb, Lub1) :-
784          set2list(Glb, Lsets),
785          set2list(Lub1, Lsets1),
786          all_union(Lsets, Union),
787          all_union(Lsets1, Union1),
788          Union `< Union1,!,
789          checkincl(Lsets,Lsets1).
790checkincl([], _Lsets1).
791checkincl([S | Lsets],Lsets1):-
792          contained(S, Lsets1),
793          checkincl(Lsets,Lsets1).
794
795contained(_S, []) :- fail,!.
796contained(S, [Ss | Lsets1]) :-
797          (S `< Ss ->
798                true
799          ;
800                contained(S, Lsets1)
801          ).
802\end{verbatim}
803
804The execution of  this constraint is dynamic, {\em i.e.}, the
805predicate \verb/incl//\verb/2/ is called and woken following the
806following steps:
807\begin{itemize}
808\item We check if the two set variables are ground \verb/set/. If so
809we just check deterministically if the first one is included (lattice
810inclusion) in the second one \verb/check_incl/. This
811predicate checks that any element of a ground set (which is a set
812itself in this case) is a subset of at least one element of the second
813set. If not it fails.
814\item We check if the first set is ground and the second is a set
815domain variable. If so, \verb/check_incl/ is called over the first
816ground set and the upper bound of the second set. If it succeeds then
817the lower bound of the set variable might not be consistent any more,
818we compute the new lower bound ({\em i.e.}, adding elements from the
819ground set in it (by using the union predicate) and we modify the bound
820\verb/modify_bound/. This predicate also wakes all concerned
821suspension lists and instantiates the set variable if its domain is
822reduced to a single set (upper bound = lower bound).
823\item We check if the second set is ground and the first one is a set
824variable. If so, \verb/check_incl/ is called over the lower bound of
825the first set and the second ground set. If it succeeds then the upper
826bound of the set variable might not be consistent any more. The new
827upper bound is computed by intersecting the first set with the upper
828bound of the set variable in the lattice acceptation \verb/large_inter/ and
829is updated \verb/modify_bound/.
830\item we check if both set variables are domain variables. If so the
831lower bound of the first set should be included in the lattice sense
832in the upper bound of the second one \verb/check//\verb/incl/. If it
833succeeds, then if the lower bound the second set is no more consistent
834we compute the new one by making the union with first sec lower bound.
835In the same way, the upper bound of the first set might not be
836consistent any more. If so, we compute the new one by intersecting (in
837the lattice acceptation) the both upper bounds to compute the new
838upper bound of the first set \verb/large_inter/. The upper bound of
839the first set variable is updated as well as the lower bound of the
840second set \verb/modify_bound/.
841\item After checking all these updates, we test if the constraint
842implies an instanciation of one of the two sets. If this is not the
843case, we have to suspend the predicate so that it is woken as soon as
844any bound of either set domain is changed. The predicate
845\verb/make_suspension//\verb/3/ can be used for any \eclipse\ module
846based on a meta-term structure. It creates a suspension, and then the
847predicate \verb/insert_suspension//\verb/4/, puts this suspension into
848the appropriate lists (woken when any bound is updated) of both set
849variables.
850\item the last action \verb/wake/ triggers the execution of all goals that are
851waiting for the updates we have made. These goals should be woken
852after inserting the new suspension, otherwise the new updates coming
853from these woken goals won't be propagated on this constraint !
854\end{itemize}
855\section{Set Domain output}
856
857The library {\bf conjunto.pl} contains output macros which print a set
858variable as well as a ground set respectively as an interval of sets or
859a set. The {\bf setdom} attribute of a set domain variable (metaterm)
860is printed in the simplified form of just the $glb..lub$ interval, e.g.
861
862\begin{verbatim}
863[eclipse 2]: S `:: {}..{a,v,c}, svar_attribute(S,A), A = set{setdom : D}.
864
865S = S{{} .. {a, c, v}}
866A = {} .. {a, c, v}
867D = [{}, {a, c, v}]
868yes.
869\end{verbatim}
870
871\section{Debugger}
872
873The \eclipse\ debugger which supports debugging and tracing of finite
874domain programs in various ways, can just be used the same way for set
875domain programs. No specific set domain debugger has been implemented
876for this release. 
877
878\begin{latexonly}
879\disableunderscores
880\end{latexonly}
881\index{library!conjunto.pl|)}
882
883