## 1.6 Connecting Finite Domain and Finite Set Constraints

The propagator in this section involves apart from finite domain constraints also finite set constraints. Its semantics is straightforward: it connects a domain variable and a set variable by projecting the changes of the constraints in both directions. Hereby, the finite domain variable designates an integer (as usual) and the set variable designates a singleton set where .

Propagation Rules

There are three propagation rules:

The last two rules propagate the changes of the upper bound of the set constraint to the domain constraint and the other way around.

### 1.6.1 The Class Definition

The class definition does not have any particularities. It follows the scheme known from previous sections.

`class ConnectProp : public OZ_Propagator {private:  static OZ_PropagatorProfile profile;protected:  OZ_Term _fs;  OZ_Term _fd;public:  ConnectProp(OZ_Term fsvar, OZ_Term fdvar)      : _fs(fsvar), _fd(fdvar)  {}    virtual void gCollect(void) {    OZ_gCollectTerm(_fd);    OZ_gCollectTerm(_fs);  }   virtual void sClone(void) {    OZ_sCloneTerm(_fd);    OZ_sCloneTerm(_fs);  }   virtual size_t sizeOf(void) {    return sizeof(ConnectProp);  }   virtual OZ_Term getParameters(void) const {    return OZ_cons(_fs, (OZ_cons(_fd, OZ_nil())));  }   virtual OZ_PropagatorProfile *getProfile(void) const {    return &profile;  }   virtual OZ_Return propagate();};`

Note that set variables are handled the same way as domain variables.

### 1.6.2 The Propagation Function

The implementation of the propagation function starts with retrieving the constrained variables from the constraint store using the constructors of the classes `OZ_FDIntVar` and `OZ_FSetVar`. The class `OZ_FSetVar` provides for the same member functions as `OZ_FDIntVar` such that handling set variables does not differ from handling domain variables.

Propagation

The propagation starts with the first rule. it uses the member function `OZ_FSetConstraint::putcard(int, int)` to impose the cardinality constraint upon . The second rule implemented by removing all elements from that are definitely not in (see Section 1.8.3 of ``The Mozart Constraint Extensions Reference'' for details on `OZ_FSetConstraint::getNotInSet()`). The last propagation rule uses the operator `OZ_FSetConstraint::operator <=` for . The constructor `OZ_FSetConstraint` is used to convert the `OZ_Finite Domain` appropriately. Note that imposing constraints on resp. are guarded by `FailOnEmpty` resp. `FailOnInvalid` to catch failures.

`OZ_Return ConnectProp::propagate() { printf("ConnectProp::propagate\n");    OZ_FDIntVar fd(_fd);  OZ_FSetVar  fs(_fs);   // 1st propagation rule  fs->putCard(1, 1);     // 2nd propagation rule  FailOnEmpty(*fd -= fs->getNotInSet());   // 3rd propagation rule  FailOnInvalid(*fs <= OZ_FSetConstraint(*fd));   return (fd.leave() | fs.leave()) ? OZ_SLEEP : OZ_ENTAILED; failure:  fd.fail(); fs.fail();  return OZ_FAILED;}`

The macro `FailOnInvalid` is define as

`#define FailOnInvalid(X) if(!(X)) goto failure;`

since finite set operator return `OZ_FALSE` in case an inconsistency occured.

The propagator closes with calling `leave()` for both variables and returning `OZ_SLEEP` resp. `OZ_ENTAILED` depending on whether not all variables denote values or they do.

### 1.6.3 The Header Function and Connecting to the Native Functor Interface

The header function uses `OZ_Expect::expectFSetVar` to check for a set variable.

`OZ_BI_define(connect, 2, 0){  OZ_EXPECTED_TYPE(OZ_EM_FSET","OZ_EM_FD);  OZ_Expect pe;  OZ_EXPECT(pe, 0, expectFSetVar);  OZ_EXPECT(pe, 1, expectIntVar);   return pe.impose(new ConnectProp(OZ_in(0), OZ_in(1)));}OZ_BI_end OZ_PropagatorProfile ConnectProp::profile;`

The predefined macro `OZ_EM_FSET` is used to produce an appropriate error message in case an type exception has to be risen.

The C part of the native functor interface is given below.

`OZ_C_proc_interface *oz_init_module(void){  static OZ_C_proc_interface i_table[] = {    {"connect", 2, 0, connect},    {0, 0, 0, 0}  };   return i_table;}`

### 1.6.4 Testing the Propagator

To make the propagator available on Oz side feed the following code:

`declare Connect = {{New Module.manager init}           link(url: 'sync.so{native}' \$)}.connect{Wait Connect}{Show Connect}`

The variable `Connect` refers to the propagator. By feeding the code below line by line one can observe (e. g. using the Browser ``The Oz Browser''), how the propagator works.

`declare S = {FS.var.decl}        I = {FD.decl}                        % S =                        I =  {Connect S I}    %  {{}..{0#134217726}}#1      {0#134217726}{FS.exclude 2 S} %  {{}..{0#1 3#134217726}}#1  {0#1 3#34217726}I :: 1#100       %  {{}..{1 3#100}}#1          {1 3#100}{FS.exclude 1 S} %  {{}..{3#100}}#1            {3#100}I <: 4           %  {3}#1                      3`

The comments at the end of each line indicate the constraints after feeding that line.

Tobias Müller
Version 1.4.0 (20080702)