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) 2006 Cisco Systems, Inc. All Rights Reserved. 18% 19% Contributor(s): 20% 21% END LICENSE BLOCK 22 23%\documentstyle[a4]{article} 24%\documentstyle[a4,html]{article} 25%\catcode`_=\active 26%\title{{\eclipse} Repair Library} 27%\author{some} 28%\begin{document} 29%\maketitle 30 31%HEVEA\cutdef[1]{section} 32%---------------------------------------------------------------------- 33\section{Introduction} 34%---------------------------------------------------------------------- 35 36\index{repair} 37The Repair library provides two simple, fundamental features which are 38the basis for the development of repair algorithms and non-monotonic 39search methods in {\eclipse}: 40\begin{itemize} 41\item The maintenance of {\em tentative values} for the problem variables. 42 These tentative values may together form a partial 43 or even inconsistent {\em tentative assignment}. 44 Modifications to, or extensions of this assignment may be 45 applied until a correct solution is found. 46 47\item The monitoring of constraints (the so called {\em repair constraints}) 48 for being either satisfied or violated under the current tentative 49 assignment. Search algorithms can then access the set of 50 constraints that are violated at any point in the search, 51 and perform repairs by changing the tentative assignment 52 of the problem variables. 53\end{itemize} 54This functionality allows the implementation of classical local search 55\index{local search} 56methods within a CLP environment (see {\em Tutorial on Search Methods}). 57However, the central aim of the Repair library is to provide a framework 58for the integration of repair-based search with the consistency techniques 59available in {\eclipse}, such as the domains and constraints of the FD library. 60 61A more detailed description of the theory and methods that are the basis of 62the Repair library is available \cite{HaniThesis}. 63 64 65\subsection{Using the Library} 66To use the repair library you need to load it using 67\begin{quote}\begin{verbatim} 68:- lib(repair). 69\end{verbatim}\end{quote} 70Normally, you will also want to load one more of the 71'fd', 'ic', 'fd_sets' or 'conjunto' solvers. This is 72because of the notion of tenability, i.e. whether a tentative value is 73in a domain is checked by communicating with a different solver that 74keeps that domain. 75 76 77%---------------------------------------------------------------------- 78\section{Tentative Values} 79%---------------------------------------------------------------------- 80\index{Tentative Values} 81 82\subsection{Attaching and Retrieving Tentative Values} 83A problem variable may be associated with a tentative value. 84Typically this tentative value is used to record preferred or 85previous assignments to this variable. 86 87\subsubsection{?Vars tent_set ++Values} 88\label{tentset} 89Assigns tentative values for the variables in a term. These are 90typically used to register values the variables are given in a partial 91or initially inconsistent solution. These values may be changed 92through later calls to the same predicate. Vars can be a variable, a 93list of variables or any nonground term. Values must be a 94corresponding ground term. The tentative values of the variables in 95Vars are set to the corresponding ground values in Values. 96 97\subsubsection{?Vars tent_get ?Values} 98Query the variable's tentative values. 99Values is a copy of the term Vars with the tentative values filled in 100place of the variables. If a variable has no tentative value 101a variable is returned in its place. 102 103 104\subsection{Tenability} 105\index{tenable} 106A problem variable is {\em tenable} when it does not have a 107tentative value or when it has a tentative value that is 108consistent e.g.\ with its finite domain. For example 109\begin{quote}\begin{verbatim} 110[eclipse 3]: fd:(X::1..5), X tent_set 3. 111X = X{fd:[1..5], repair:3} 112\end{verbatim}\end{quote} 113produces a tenable variable (note how the tentative value is printed 114as the variable's repair-attribute), while on the other hand 115\begin{quote}\begin{verbatim} 116[eclipse 3]: fd:(X::1..5), X tent_set 7. 117X = X{fd:[1..5], repair:7} 118\end{verbatim}\end{quote} 119produces an untenable variable. Note that, unlike logical assignments, 120the tentative value can be changed: 121\begin{quote}\begin{verbatim} 122[eclipse 3]: fd:(X::1..5), X tent_set 7, X tent_set 3. 123X = X{fd:[1..5], repair:3} 124\end{verbatim}\end{quote} 125 126\subsubsection{tenable(?Var)} 127Succeeds if the given variable is tenable. This predicate is the link 128between repair and any underlying solver that maintains a domain for 129a variable\footnote{ 130If you wish to write your own solver and have it cooperate with repair 131you have to define a test_unify handler}. 132 133 134\subsection{The Tentative Assignment} 135\index{tentative assignment} 136The notion of a {\em tentative assignment} is the means of integration 137with the consistency methods of {\eclipse}. The tentative assignment 138is used for identifying whether a repair constraint is being violated. 139 140The tentative assignment is a function of the groundness and tenability of 141problem variables according to the following table 142\vspace{0.2cm} 143\noindent 144\begin{center} 145\begin{tabular}{||l|l|l||} \hline \hline 146\label{table} 147Variable Groundness & Variable Tenability & Value in Tentative Assignment \\ \hline 148Ground & Tenable & Ground Value \\ 149Ground & Not Tenable & Ground Value \\ 150Not Ground & Tenable & Tentative Value \\ 151Not Ground & Not Tenable & Undefined \\ 152 153\hline \hline 154\end{tabular} 155\end{center} 156\vspace{0.5cm} 157A repair constraint is violated under two conditions: 158\begin{itemize} 159\item The tentative assignment is undefined for any of its variables. 160\item The constraint fails under the tentative assignment. 161\end{itemize} 162 163 164\subsection{Variables with No Tentative Value} 165It has been noted above that variables with no associated tentative value 166are considered to be 167tenable. Since no single value has been selected as a tentative value, 168the Repair library checks constraints for consistency with respect to the domain of 169that variable. A temporary variable with identical domains is substituted 170in the constraint check. 171 172\subsection{Unification} 173 174If two variables with distinct tentative values are unified only one 175 is kept for the unified variable. Preference is given to a tentative 176value that would result in a tenable unified variable. 177 178\subsection{Copying} 179 180If a variable with a repair attribute is copied using 181\bipref{copy_term/2}{../bips/kernel/termmanip/copy_term-2.html} 182or similar, the repair attribute is stripped. If you wish the copy to have 183the same tentative value as the original, you will need to call 184\bipref{tent_get/2}{../bips/lib/repair/tent_get-2.html} 185and 186\bipref{tent_set/2}{../bips/lib/repair/tent_set-2.html} 187yourself. 188 189 190%---------------------------------------------------------------------- 191\section{Repair Constraints} 192%---------------------------------------------------------------------- 193 194Once a constraint has been declared to be a repair constraint it 195is monitored for violation. Whether a repair 196\index{violation} 197constraint is considered to be violated depends on the states of 198its variables. A temporary assignment of the variables is used 199for checking constraints. This assignment is called the 200{\em tentative assignment} and is described above. 201A constraint which is violated in this way is called a 202\index{conflict constraint} 203{\em conflict constraint}. 204 205\index{annotation} 206\index{constraint annotation} 207Normal constraints are turned into repair constraints by giving them 208one of the following annotations: 209 210\subsubsection{Constraint r_conflict ConflictSet} 211\index{r_conflict/2} 212This is the simplest form of annotation. 213\bipref{r_conflict/2}{../bips/lib/repair/r_conflict-2.html} 214makes a constraint known 215to the repair library, i.e.\ it will initiate monitoring of 216{\bf Constraint} for conflicts. 217When the constraint goes into conflict, it will show up in the 218conflict set denoted by {\bf ConflictSet}, from where it can be 219retrieved using \bipref{conflict_constraints/2}{../bips/lib/repair/conflict_constraints-2.html}. 220{\bf Constraint} can be any goal that works logically, it should be useable 221as a ground check, and work on any instantiation pattern. Typically, 222it will be a constraint from some solver library. 223{\bf ConflictSet} can be a user-defined name (an atom) or it can be 224a variable in which case the system returns a conflict set handle that can 225later be passed to \bipref{conflict_constraints/2}{../bips/lib/repair/conflict_constraints-2.html}. Example constraint with 226annotation: 227\begin{quote}\begin{verbatim} 228fd:(Capacity >= sum(Weights)) r_conflict cap_cstr 229\end{verbatim}\end{quote} 230Note that using different conflict sets for different groups of constraints 231will often make the search algorithm easier and more efficient. 232A second allowed form of the 233\bipref{r_conflict/2}{../bips/lib/repair/r_conflict-2.html} 234annotation is 235{\bf Constraint r_conflict ConflictSet-ConflictData}. 236If this is used, {\bf ConflictData} will appear in the conflict 237set instead of the {\bf Constraint} itself. 238This feature can be used to pass additional information to the 239search algorithm. 240 241 242\subsubsection{Constraint r_conflict_prop ConflictSet} 243\index{r_conflict_prop/2} 244In addition to what 245\bipref{r_conflict/2}{../bips/lib/repair/r_conflict-2.html} 246does, the 247\bipref{r_conflict_prop/2}{../bips/lib/repair/r_conflict_prop-2.html} 248annotation causes the 249{\bf Constraint} to be activated as a goal as soon as it goes into 250conflict for the first time. If {\bf Constraint} is a finite-domain 251constraint for example, this means that domain-based propagation on 252{\bf Constraint} will start at that point in time. 253 254Note that if you want constraint propagation from the very beginning, 255you should simply write the constraint twice, once without and once 256with annotation. 257 258 259%---------------------------------------------------------------------- 260\section{Conflict Sets} 261%---------------------------------------------------------------------- 262 263Given a tentative assignment, there are two kinds of conflicts that 264can occur: 265\begin{itemize} 266\item Untenable variables 267\item Violated constraints 268\end{itemize} 269To obtain a tentative assignment which is a solution to the given problem, 270both kinds of conflicts must be repaired. 271The repair library supports this task by dynamically maintaining 272conflict sets. 273Typically, a search algorithm examines the conflict set(s) and attempts 274to repair the tentative assignment such that the conflicts disappear. 275When all conflict sets are empty, a solution is found. 276 277\subsubsection{conflict_vars(-Vars)} 278\index{conflict variables} 279\index{conflict_vars/1} 280When a variable becomes untenable, it appears in the set of conflict 281variable, when it becomes tenable, it disappears. 282This primitive returns the list of all currently untenable variables. 283Note that all these variables must be reassigned in any solution 284(there is no other way to repair untenability). 285Variable reassignment can be achieved 286by changing the variable's tentative value with tent_set/2, 287or by instantiating the variable. 288Care should be taken whilst implementing repairs through tentative 289value changes since this is a non-monotonic operation: conflicting repairs 290may lead to cycles and the computation may not terminate. 291 292 293\subsubsection{conflict_constraints(+ConflictSet, -Constraints)} 294\index{conflict constraints} 295\index{conflict_constraints/2} 296When a repair constraint goes into conflict (i.e.\ when it does not satisfy 297the tentative assignment of its variables), it appears in a conflict set, 298once it satisfies the tentative assignment, it disappears. 299This primitive returns the list of all current conflict constraints 300in the given conflict set. 301{\bf ConflictSet} is the conflict set name (or handle) which has 302been used in the corresponding constraint annotation. For example 303\begin{quote}\begin{verbatim} 304conflict_constraints(cap_cstr, Conflicts) 305\end{verbatim}\end{quote} 306would retrieve all constraints that were annotated with \verb+cap_cstr+ 307and are currently in conflict. 308 309At least one variable within a conflict constraint must be reassigned 310to get a repaired solution. 311Variable reassignment can be achieved 312by changing the variable's tentative value with tent_set/2, 313or by instantiating the variable. 314Care should be taken whilst implementing repairs through tentative 315value changes since this is a non-monotonic operation: conflicting repairs 316may lead to cycles and the computation may not terminate. 317 318Note that any repair action can change the conflict set, 319therefore \bipref{conflict_constraints/2}{../bips/lib/repair/conflict_constraints-2.html} should be called again after 320a change has been made, in order to obtain an up-to-date conflict set. 321 322 323\subsubsection{poss_conflict_vars(+ConflictSet, -Vars)} 324\index{poss_conflict_vars/2} 325The set of variables within the conflict constraints. 326This is generally a mixture of tenable and untenable variables. 327 328 329 330%\subsubsection{Constraint r} 331%Annotated constraint. Makes a constraint known to the repair 332%algorithm. Calling 'Constraint' this way will initiate monitoring 333%of 'Constraint' by the Repair library. The 334%propagation of this constraint is delayed until it becomes a {\em conflict 335%constraint} (see Sect.~\ref{definitions}). 336%\par Operationally a Repair library delayed goal performs tentative assignment 337%checks to determine whether Constraint is violated. At the first violation 338%Constraint is called to achieve subsequent propagation on its variables. 339% 340%\subsubsection{Constraint r_no_prop} 341%A passive version of predicate 'r' that does not propagate the constraint 342%in question even after it is found to be violated. Since it is never 343%propagated, 'Constraint' can be a goal that only work as a ground test. 344% 345%\subsubsection{Constraint r_prop} 346%An active version of predicate 'r' that immediately propagates the constraint 347%in question rather than waiting for it to be violated. 348% 349%It is always more efficient (and equivalent in meaning) to simply call the 350%constraint and then call it again with the r_no_prop annotation, since 351%this lets \eclipse compile the constraint, rather than meta-calling it. 352 353 354%---------------------------------------------------------------------- 355\section{Invariants} 356%---------------------------------------------------------------------- 357 358For writing sophisticated search algorithms it is useful to be able 359not only to detect conflicts caused by tentative value changes, 360but also to compute consequences of these changes. 361For example, it is possible to repair certain constraints automatically 362by (re)computing one or more of their variable's tentative values 363based on the others (e.g.\ a sum constraint can be repaired by updating 364the tentative value of the sum variable whenever the tentative value of one of 365the other variables changes). 366We provide two predicates for this purpose: 367 368\subsubsection{-Result tent_is +Expression} 369\index{tent_is/2} 370This is similar to the normal arithmetic 371\bipref{is/2}{../bips/kernel/arithmetic/is-2.html} 372predicate, but evaluates the expression based on the tentative 373assignment of its variables. The result is delivered as (an update to) 374the tentative value of the Result variable. 375Once initiated, {\bf tent_is} will stay active and keep updating Result's 376tentative value eagerly whenever the tentative assignment of any 377variable in Expression changes. 378 379\subsubsection{tent_call(In, Out, Goal)} 380\index{tent_call/3} 381This is a completely general meta-predicate to support computations 382with tentative values. Goal is a general goal, and In and Out are 383lists (or other terms) containing subsets of Goal's variables. 384A copy of Goal is called, with the In-variables replaced by their 385tentative values and the Out-variables replaced by fresh variables. 386Goal is expected to return values for the Out variables. These values 387are then used to update the tentative values of the original Out variables. 388This process repeats whenever the tentative value of any In-variable 389changes. 390 391 392\subsubsection{Waking on Tentative Assignment Change} 393The predicates \bipref{tent_is/2}{../bips/lib/repair/tent_is-2.html} and \bipref{tent_call/3}{../bips/lib/repair/tent_call-3.html} are implemented 394\index{suspension list!ga_chg} 395using the {\bf ga_chg} suspension list which is attached to every 396repair variable. The programmer has therefore all the tools to write 397specialised, efficient versions of tent_call/3. 398Follow the following pattern: 399\begin{quote} \begin{verbatim} 400my_invariant(In, Out) :- 401 In tent_get TentIn, 402 ... compute TentOut from TentIn ... 403 suspend(my_invariant(In,Out,Susp), 3, [In->ga_chg]), 404 Out tent_set TentOut. 405\end{verbatim} \end{quote} 406This can be made more efficient by using a demon (\bipref{demon/1}{../bips/kernel/compiler/demon-1.html}). 407 408 409%---------------------------------------------------------------------- 410\section{Examples} 411%---------------------------------------------------------------------- 412More examples of repair library use, in particular in the area 413of local search, can be found in the {\em Tutorial on Search Methods}. 414 415\subsection{Interaction with Propagation} 416 417\index{propagation} 418In the following example, we set up three constraints as both repair and 419fd-constraints (using the {\bf r_conflict_prop} annotation) and 420install an initial tentative assignment (using {\bf tent_set}). 421We then observe the result by retrieving the conflict sets: 422\begin{quote} 423\begin{verbatim} 424[eclipse 1]: lib(repair), lib(fd). % libraries needed here 425yes. 426[eclipse 2]: 427 fd:([X,Y,Z]::1..3), % the problem variables 428 fd:(Y #\= X) r_conflict_prop confset, % state the constraints 429 fd:(Y #\= Z) r_conflict_prop confset, 430 fd:(Y #= 3) r_conflict_prop confset, 431 [X,Y,Z] tent_set [1,2,3], % set initial assignment 432 [X,Y,Z] tent_get [NewX,NewY,NewZ], % get repaired solution 433 conflict_constraints(confset, Cs), % see the conflicts 434 conflict_vars(Vs). 435 436X = X{fd:[1..3], repair:1} 437Y = 3 438Z = Z{fd:[1, 2], repair:3} 439NewX = 1 440NewY = 3 441NewZ = 3 442Cs = [3 #\= Z{fd:[1, 2], repair:3}] 443Vs = [Z{fd:[1, 2], repair:3}] 444 445Delayed goals: 446 ... 447yes. 448\end{verbatim} 449\end{quote} 450Initially only the third constraint \verb+Y #= 3+ is inconsistent with the 451tentative assignment. According to the definition of {\bf r_conflict_prop} 452this leads to 453the constraint \verb+Y #= 3+ being propagated, which causes Y to be intantiated to 3 454thus rendering the tentative value (2) irrelevant. 455 456Now the constraint \verb+Y #\= Z+, is in conflict since Y is now 3 and Z has the 457tentative value 3 as well. The constraint starts to propagate and removes 3 458from the domain of \verb+Z [1..2]+. 459 460As a result Z becomes a conflict variable since its tentative value (3) 461is no longer in its domain. The \verb+Y #\= Z+ constraint remains in the 462conflict constraint set because Z has no valid tentative assignment. 463 464The constraint \verb+Y #\= X+ is not affected, it neither goes into conflict 465nor is its fd-version ever activated. 466 467To repair the remaining conflicts and to find actual solutions, 468the \verb+repair/0+ predicate described below could be used. 469 470 471\subsection{Repair Labeling} 472\label{labeling} 473This is an example for how to use the information provided by the repair 474library to improve finite domain labeling. 475\index{repair/1} 476You can find the repair/1 predicate in the 'repairfd' library file. 477\begin{quote} \begin{verbatim} 478repair(ConflictSet) :- 479 ( conflict_vars([C|_]) -> % label conflict 480 indomain(C), % variables first 481 repair(ConflictSet) 482 ; conflict_constraints(ConflictSet, [C|_]) -> 483 term_variables(C, Vars), % choose one variable in 484 deleteffc(Var,Vars, _), % the conflict constraint 485 Var tent_get Val, 486 (Var = Val ; fd:(Var #\= Val)), 487 repair(ConflictSet) 488 ; % no more conflicts: 489 true % a solution is found. 490 ). 491\end{verbatim} \end{quote} 492The predicate is recursive and terminates when there are no more variables 493or constraints in conflict. 494 495Repair search often finishes without labeling all variables, a 496solution has been found and a set of tenable variables are still 497uninstantiated. Thus even after the search is finished, Repair library 498delayed goals used for monitoring constraints will be present in 499anticipation of further changes. 500 501To remove them one has to ground these tenable variables to their 502tentative values. 503 504Note that the example code never changes tentative values. 505This has the advantage that this is still a complete, monotonic and 506cycle-free algorithm. 507However, it is not very realistic when the problem is difficult and 508the solution is not close enough to the initial tentative assignment. 509In that case, one would like to exploit the observation that it is often 510possible to repair some conflict constraints by changing tentative 511values. During search one would update the tentative values to be as 512near as pssible to what one wants while maintaining consistency. If the 513search leads to a failure these changes are of course undone. 514 515%HEVEA\cutend 516