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