Like IC and FD solvers, GFD has facilities to allow the extension of the solver library so that GFD can co-operate with other solvers in solving a problem, and also to allow the user to define their own constraints at the ECLiPSe level. This is achieved by providing a suspension list with the gfd attribute, which allows for the data-driven programming needed by solver co-operation and constraint propagation, and a set of low-level predicates to process, query and modify the domain of problem variables.
These facilities allow solver co-operation and user-defined constraints propagation at the ECLiPSe level, and not within Gecode directly. So, search then must be done at the ECLiPSe level, i.e. not through Gecode’s search engines. The performance of constraints defined in this way will very likely be less efficient than implementing the constraints directly in Gecode.
The GFD attribute is a meta-term which is attached to all GFD problem variables. Many of the fields of the attribute are used for implementing the interface to Gecode, and are of no interest to the user. The only field of interest is the any field, which is for the any suspension list, which is woken on any change in the domain of the variable:
gfd{ .... any:SuspAny, .... }
The any suspension list has the same waking behaviour as the any suspension list of FD, and is sufficient for implementing constraints – the other suspension lists found in IC and FD are specialisations of the any suspension list, in that they provide more precise waking conditions. The reason that only one suspension list is provided by GFD is to minimise the overhead in normal use of the solver.
In addition to waking the attribute’s any suspension list, the constrained suspension list will also be woken when a GFD variable’s domain is changed, and the inst suspension list will be woken if the variable is bound.
The suspension lists allow constraint propagation to be implemented at the ECLiPSe level, which is distinct from the propagation of “native” Gecode constraints, where each propagation phase (and in the case of using the search engine, the whole search) is an atomic step at the ECLiPSe level. This has a similar effect to running all “native” propagations at a higher (more urgent) priority.
As only the any suspension list is provided, some rewriting of existing user-defined constraints for IC and FD may be needed when such code is ported for GFD.
Like IC, GFD provides a set of predicates to modify the domain of GFD variables to support the writing of new constraints. Unlike normal constraints, no Gecode level propagation or waking of other suspended goals (such as scheduled by other ECLiPSe level constraints) occurs with these predicates.
With the exception of impose_bounds/3 none of the goals call wake/0, so the programmer is free to do so at a convenient time.
Some of these predicates are provided for compatibility with IC, as these predicates have the same name and similar semantics to their IC counter-parts (including the waking behaviour for impose_bounds/3). However, due to the difference in the way domains are represented in IC and Gecode, these predicates may be inefficient for use with Gecode, particularly if you need to modify multiple variables and/or multiple domain values. The predicates with names that begin with gfd_vars are specific to GFD and are designed to be more efficient than their IC compatible counter-parts.
The “native” primitives are:
The IC-compatible primitives are:
These predicates are used to retrieve various properties of a domain variable (and usually work on integers as well).
In most cases, the property is obtained directly from Gecode. Many of these properties are useful for selecting a variable for labelling. Here are some examples:
+Result
argument
binds Result instead.