update docs
This commit is contained in:
@@ -1,3 +1,32 @@
|
||||
/**
|
||||
@defgroup Gecode_and_ClPbBFDbC Programming Finite Domain Constraints in YAP/Gecode
|
||||
@ingroup Gecode
|
||||
@{
|
||||
|
||||
The gecode/clp(fd) interface is designed to use the GECODE functionality
|
||||
in a more CLP like style. It requires
|
||||
|
||||
~~~~~{.prolog}
|
||||
:- use_module(library(gecode/clpfd)).
|
||||
~~~~~
|
||||
Several example programs are available with the distribution.
|
||||
|
||||
Integer variables are declared as:
|
||||
|
||||
+ _V_ in _A_.. _B_
|
||||
declares an integer variable _V_ with range _A_ to _B_.
|
||||
+ _Vs_ ins _A_.. _B_
|
||||
declares a set of integer variabless _Vs_ with range _A_ to _B_.
|
||||
+ boolvar( _V_)
|
||||
declares a boolean variable.
|
||||
+ boolvars( _Vs_)
|
||||
declares a set of boolean variable.
|
||||
|
||||
|
||||
Constraints supported are:
|
||||
|
||||
*/
|
||||
|
||||
:- module(gecode_clpfd, [
|
||||
op(100, yf, []),
|
||||
op(760, yfx, #<==>),
|
||||
@@ -199,22 +228,43 @@ process_constraints(B, B, _Env).
|
||||
get_home(Env),
|
||||
check(A, NA),
|
||||
post( rel(NA, (#=)), Env, _).
|
||||
/** @pred _X_ #= is det
|
||||
all elements of _X_ must take the same value
|
||||
|
||||
*/
|
||||
( A #\= ) :-
|
||||
get_home(Env),
|
||||
check(A, NA),
|
||||
post( rel(NA, (#\=)), Env, _).
|
||||
/** @pred _X_ #< is det
|
||||
elements of _X_ must be decreasing or equal
|
||||
|
||||
|
||||
*/
|
||||
( A #< ) :-
|
||||
get_home(Env),
|
||||
check(A, NA),
|
||||
post( rel(NA, (#<)), Env, _).
|
||||
/** @pred _X_ #> is det
|
||||
elements of _X_ must be increasing
|
||||
|
||||
*/
|
||||
( A #> ) :-
|
||||
get_home(Env),
|
||||
check(A, NA),
|
||||
post( rel(NA, (#>)), Env, _).
|
||||
/** @pred _X_ #=< is det
|
||||
elements of _X_ must be decreasing
|
||||
|
||||
*/
|
||||
( A #=< ) :-
|
||||
get_home(Env),
|
||||
check(A, NA),
|
||||
post( rel(NA, (#=<) ), Env, _).
|
||||
/** @pred _X_ #>= is det
|
||||
elements of _X_ must be increasinga or equal
|
||||
|
||||
*/
|
||||
( A #>= ) :-
|
||||
get_home(Env),
|
||||
check(A, NA),
|
||||
@@ -1147,3 +1197,6 @@ l(NV, OV, A, B, [_|Vs]) :-
|
||||
|
||||
is_one(1).
|
||||
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
@@ -16,9 +16,258 @@
|
||||
%% along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
%%=============================================================================
|
||||
|
||||
/** @defgroup Gecode Gecode Interface
|
||||
|
||||
@ingroup YAPPackages
|
||||
@{
|
||||
|
||||
|
||||
The gecode library intreface was designed and implemented by Denis
|
||||
Duchier, with recent work by Vítor Santos Costa to port it to version 4
|
||||
of gecode and to have an higher level interface,
|
||||
|
||||
|
||||
@defgroup The_Gecode_Interface The Gecode Interface
|
||||
@ingroup Gecode
|
||||
@{
|
||||
|
||||
This text is due to Denys Duchier. The gecode interface requires
|
||||
|
||||
~~~~~{.prolog}
|
||||
:- use_module(library(gecode)).
|
||||
~~~~~
|
||||
Several example programs are available with the distribution.
|
||||
|
||||
+ CREATING A SPACE
|
||||
|
||||
A space is gecodes data representation for a store of constraints:
|
||||
|
||||
~~~~~{.prolog}
|
||||
Space := space
|
||||
~~~~~
|
||||
|
||||
+ CREATING VARIABLES
|
||||
|
||||
Unlike in Gecode, variable objects are not bound to a specific Space. Each one
|
||||
actually contains an index with which it is possible to access a Space-bound
|
||||
Gecode variable. Variables can be created using the following expressions:
|
||||
|
||||
~~~~~{.prolog}
|
||||
IVar := intvar(Space,SPEC...)
|
||||
BVar := boolvar(Space)
|
||||
SVar := setvar(Space,SPEC...)
|
||||
~~~~~
|
||||
|
||||
where SPEC... is the same as in Gecode. For creating lists of variables use
|
||||
the following variants:
|
||||
|
||||
~~~~~{.prolog}
|
||||
IVars := intvars(Space,N,SPEC...)
|
||||
BVars := boolvars(Space,N,SPEC...)
|
||||
SVars := setvars(Space,N,SPEC...)
|
||||
~~~~~
|
||||
|
||||
where N is the number of variables to create (just like for XXXVarArray in
|
||||
Gecode). Sometimes an IntSet is necessary:
|
||||
|
||||
~~~~~{.prolog}
|
||||
ISet := intset([SPEC...])
|
||||
~~~~~
|
||||
|
||||
where each SPEC is either an integer or a pair (I,J) of integers. An IntSet
|
||||
describes a set of ints by providing either intervals, or integers (which stand
|
||||
for an interval of themselves). It might be tempting to simply represent an
|
||||
IntSet as a list of specs, but this would be ambiguous with IntArgs which,
|
||||
here, are represented as lists of ints.
|
||||
|
||||
~~~~~{.prolog}
|
||||
Space += keep(Var)
|
||||
Space += keep(Vars)
|
||||
~~~~~
|
||||
|
||||
Variables can be marked as "kept". In this case, only such variables will be
|
||||
explicitly copied during search. This could bring substantial benefits in
|
||||
memory usage. Of course, in a solution, you can then only look at variables
|
||||
that have been "kept". If no variable is marked as "kept", then they are all
|
||||
kept. Thus marking variables as "kept" is purely an optimization.
|
||||
|
||||
+ CONSTRAINTS AND BRANCHINGS
|
||||
|
||||
all constraint and branching posting functions are available just like in
|
||||
Gecode. Wherever a XXXArgs or YYYSharedArray is expected, simply use a list.
|
||||
At present, there is no support for minimodel-like constraint posting.
|
||||
Constraints and branchings are added to a space using:
|
||||
|
||||
~~~~~{.prolog}
|
||||
Space += CONSTRAINT
|
||||
Space += BRANCHING
|
||||
~~~~~
|
||||
|
||||
For example:
|
||||
|
||||
~~~~~{.prolog}
|
||||
Space += rel(X,'IRT_EQ',Y)
|
||||
~~~~~
|
||||
|
||||
arrays of variables are represented by lists of variables, and constants are
|
||||
represented by atoms with the same name as the Gecode constant
|
||||
(e.g. 'INT_VAR_SIZE_MIN').
|
||||
|
||||
+ SEARCHING FOR SOLUTIONS
|
||||
|
||||
~~~~~{.prolog}
|
||||
SolSpace := search(Space)
|
||||
~~~~~
|
||||
|
||||
This is a backtrackable predicate that enumerates all solution spaces
|
||||
(SolSpace). It may also take options:
|
||||
|
||||
~~~~~{.prolog}
|
||||
SolSpace := search(Space,Options)
|
||||
~~~~~
|
||||
|
||||
Options is a list whose elements maybe:
|
||||
|
||||
+ restart
|
||||
to select the Restart search engine
|
||||
+ threads=N
|
||||
to activate the parallel search engine and control the number of
|
||||
workers (see Gecode doc)
|
||||
+ c_d=N
|
||||
to set the commit distance for recomputation
|
||||
+ a_d=N
|
||||
to set the adaptive distance for recomputation
|
||||
|
||||
|
||||
|
||||
+ EXTRACTING INFO FROM A SOLUTION
|
||||
|
||||
An advantage of non Space-bound variables, is that you can use them both to
|
||||
post constraints in the original space AND to consult their values in
|
||||
solutions. Below are methods for looking up information about variables. Each
|
||||
of these methods can either take a variable as argument, or a list of
|
||||
variables, and returns resp. either a value, or a list of values:
|
||||
|
||||
~~~~~{.prolog}
|
||||
Val := assigned(Space,X)
|
||||
|
||||
Val := min(Space,X)
|
||||
Val := max(Space,X)
|
||||
Val := med(Space,X)
|
||||
Val := val(Space,X)
|
||||
Val := size(Space,X)
|
||||
Val := width(Space,X)
|
||||
Val := regret_min(Space,X)
|
||||
Val := regret_max(Space,X)
|
||||
|
||||
Val := glbSize(Space,V)
|
||||
Val := lubSize(Space,V)
|
||||
Val := unknownSize(Space,V)
|
||||
Val := cardMin(Space,V)
|
||||
Val := cardMax(Space,V)
|
||||
Val := lubMin(Space,V)
|
||||
Val := lubMax(Space,V)
|
||||
Val := glbMin(Space,V)
|
||||
Val := glbMax(Space,V)
|
||||
Val := glb_ranges(Space,V)
|
||||
Val := lub_ranges(Space,V)
|
||||
Val := unknown_ranges(Space,V)
|
||||
Val := glb_values(Space,V)
|
||||
Val := lub_values(Space,V)
|
||||
Val := unknown_values(Space,V)
|
||||
~~~~~
|
||||
|
||||
+ DISJUNCTORS
|
||||
|
||||
Disjunctors provide support for disjunctions of clauses, where each clause is a
|
||||
conjunction of constraints:
|
||||
|
||||
~~~~~{.prolog}
|
||||
C1 or C2 or ... or Cn
|
||||
~~~~~
|
||||
|
||||
Each clause is executed "speculatively": this means it does not affect the main
|
||||
space. When a clause becomes failed, it is discarded. When only one clause
|
||||
remains, it is committed: this means that it now affects the main space.
|
||||
|
||||
Example:
|
||||
|
||||
Consider the problem where either X=Y=0 or X=Y+(1 or 2) for variable X and Y
|
||||
that take values in 0..3.
|
||||
|
||||
~~~~~{.prolog}
|
||||
Space := space,
|
||||
[X,Y] := intvars(Space,2,0,3),
|
||||
~~~~~
|
||||
|
||||
First, we must create a disjunctor as a manager for our 2 clauses:
|
||||
|
||||
~~~~~{.prolog}
|
||||
Disj := disjunctor(Space),
|
||||
~~~~~
|
||||
|
||||
We can now create our first clause:
|
||||
|
||||
~~~~~{.prolog}
|
||||
C1 := clause(Disj),
|
||||
~~~~~
|
||||
|
||||
This clause wants to constrain X and Y to 0. However, since it must be
|
||||
executed "speculatively", it must operate on new variables X1 and Y1 that
|
||||
shadow X and Y:
|
||||
|
||||
~~~~~{.prolog}
|
||||
[X1,Y1] := intvars(C1,2,0,3),
|
||||
C1 += forward([X,Y],[X1,Y1]),
|
||||
~~~~~
|
||||
|
||||
The forward(...) stipulation indicates which global variable is shadowed by
|
||||
which clause-local variable. Now we can post the speculative clause-local
|
||||
constraints for X=Y=0:
|
||||
|
||||
~~~~~{.prolog}
|
||||
C1 += rel(X1,'IRT_EQ',0),
|
||||
C1 += rel(Y1,'IRT_EQ',0),
|
||||
~~~~~
|
||||
|
||||
We now create the second clause which uses X2 and Y2 to shadow X and Y:
|
||||
|
||||
~~~~~{.prolog}
|
||||
C2 := clause(Disj),
|
||||
[X2,Y2] := intvars(C2,2,0,3),
|
||||
C2 += forward([X,Y],[X2,Y2]),
|
||||
~~~~~
|
||||
|
||||
However, this clause also needs a clause-local variable Z2 taking values 1 or
|
||||
2 in order to post the clause-local constraint X2=Y2+Z2:
|
||||
|
||||
~~~~~{.prolog}
|
||||
Z2 := intvar(C2,1,2),
|
||||
C2 += linear([-1,1,1],[X2,Y2,Z2],'IRT_EQ',0),
|
||||
~~~~~
|
||||
|
||||
Finally, we can branch and search:
|
||||
|
||||
~~~~~{.prolog}
|
||||
Space += branch([X,Y],'INT_VAR_SIZE_MIN','INT_VAL_MIN'),
|
||||
SolSpace := search(Space),
|
||||
~~~~~
|
||||
|
||||
and lookup values of variables in each solution:
|
||||
|
||||
~~~~~{.prolog}
|
||||
[X_,Y_] := val(SolSpace,[X,Y]).
|
||||
~~~~~
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
:- module(gecode, [(:=)/2, op(500, xfx, ':='),
|
||||
(+=)/2, op(500, xfx, '+=')]).
|
||||
|
||||
|
||||
:- use_module(library(debug)).
|
||||
|
||||
:- op(500, xfx, ':=').
|
||||
|
Reference in New Issue
Block a user