This file is indexed.

/usr/share/mozart/doc/cpitut/node3.html is in mozart-doc 1.4.0-8ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

1
2
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>1.2 Getting Started</TITLE><LINK href="ozdoc.css" rel="stylesheet" type="text/css"></HEAD><BODY><TABLE align="center" border="0" cellpadding="6" cellspacing="6" class="nav"><TR bgcolor="#DDDDDD"><TD><A href="node2.html#u_basic_concepts">&lt;&lt; Prev</A></TD><TD><A href="node1.html">- Up -</A></TD><TD><A href="node4.html#u_replacing">Next &gt;&gt;</A></TD></TR></TABLE><DIV id="u_getting_started"><H2><A name="u_getting_started">1.2 Getting Started</A></H2><P>This section makes the reader familiar with the C<SPAN class="allcaps">PI</SPAN> by implementing a propagator for the constraint <IMG alt="x+y=z" src="latex1.png"> and explains the steps to be taken to get it running. </P><DIV id="u_getting_started.prerequisites"><H3><A name="u_getting_started.prerequisites">1.2.1 Prerequisites</A></H3><P>The implementation of new propagators via the C<SPAN class="allcaps">PI</SPAN> requires a correctly installed Oz system. The following points should be obeyed. </P><DL><DT>Include File. </DT><DD><P>To obtain the functionality provided by the C<SPAN class="allcaps">PI</SPAN> include the file <CODE>mozart_cpi.hh</CODE> in the appropriate C/C++ source files. </P></DD><DT>Platform-independent compilation and linkage of native functors. </DT><DD><P>Use <CODE>oztool</CODE> to compile C/C++ source programs (<CODE>oztool&nbsp;c++</CODE>) and to link object files (<CODE>oztool&nbsp;ld</CODE>). It has the right options resp. search paths set depending on your current platform and environment. See <A href="../apptut/node20.html#section.counter.global.compilation">Section&nbsp;15.2 of ``Application Programming''</A> for details on <CODE>oztool</CODE>. </P></DD><DT>Naming Conventions. </DT><DD><P>Identifiers starting with <CODE>OZ_</CODE> are provided by the C<SPAN class="allcaps">PI</SPAN> and must not be defined by the programmer. </P></DD></DL><P> </P></DIV><DIV id="u_getting_started.building"><H3><A name="u_getting_started.building">1.2.2 Building a Propagator</A></H3><P>This section explains by means of an example the constraint propagator interface of Oz. We implement the propagator for the constraint <IMG alt="x+y=z" src="latex1.png">. For the sake of clarity we use a rather straightforward algorithm here. The operational semantics will provide as much pruning/propagation as possible. This is in contrast to the constraint <IMG alt="x+y=z" src="latex1.png"> supplied by the finite domain library (see <A href="../system/node25.html#section.fd.misc">Section&nbsp;5.11 of ``System Modules''</A>), which reasons only over bounds of domains. </P><DIV id="u_getting_started.building.def"><H4><A name="u_getting_started.building.def">A Propagator's Class Definition</A></H4><DIV class="apropos"><P class="margin">C<SPAN class="allcaps">PI</SPAN> class <CODE>OZ_Propagator</CODE></P><P> The emulator requires a uniform way to refer to all instances of propagators. This is realised by providing the class <CODE>OZ_Propagator</CODE>, which is the class all propagators have to be inherited from. Therefore, the emulator can refer to any propagator by a pointer of type <CODE>(OZ_Propagator&nbsp;<SPAN class="keyword">*</SPAN>)</CODE> The class <CODE>OZ_Propagator</CODE> is in terms of C++ a so-called <EM>abstract base class</EM>, i.&nbsp;e. no object of such a class can be created (since for at least one member function intentionally no implementation is provided, indicated by an appended <CODE>=0</CODE>. Instead, it defines the minimal functionality required of all classes inherited from it. The following code depicts a fragment of the definition of the class <CODE>OZ_Propagator</CODE> defined by the C<SPAN class="allcaps">PI</SPAN> (in the file <CODE>mozart_cpi<SPAN class="keyword">.</SPAN>hh</CODE>). It shows all member functions which have to be defined in a derived class. </P><BLOCKQUOTE class="linenumbers"><PRE><SPAN class="keyword">class</SPAN>&nbsp;<SPAN class="type">OZ_Propagator</SPAN>&nbsp;{<BR><SPAN class="keyword">public</SPAN>:<BR>&nbsp;&nbsp;<SPAN class="functionname">OZ_Propagator</SPAN>(<SPAN class="type">void</SPAN>);<BR>&nbsp;&nbsp;<SPAN class="keyword">virtual</SPAN>&nbsp;<SPAN class="type">OZ_Term</SPAN>&nbsp;<SPAN class="functionname">getParameters</SPAN>(<SPAN class="type">void</SPAN>)&nbsp;<SPAN class="keyword">const</SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;0;<BR>&nbsp;&nbsp;<SPAN class="keyword">virtual</SPAN>&nbsp;<SPAN class="type">size_t</SPAN>&nbsp;<SPAN class="functionname">sizeOf</SPAN>(<SPAN class="type">void</SPAN>)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;0;<BR>&nbsp;&nbsp;<SPAN class="keyword">virtual</SPAN>&nbsp;<SPAN class="type">void</SPAN>&nbsp;<SPAN class="functionname">gCollect</SPAN>(<SPAN class="type">void</SPAN>)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;0;<BR>&nbsp;&nbsp;<SPAN class="keyword">virtual</SPAN>&nbsp;<SPAN class="type">void</SPAN>&nbsp;<SPAN class="functionname">sClone</SPAN>(<SPAN class="type">void</SPAN>)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;0;<BR>&nbsp;&nbsp;<SPAN class="keyword">virtual</SPAN>&nbsp;<SPAN class="type">OZ_Return</SPAN>&nbsp;<SPAN class="functionname">propagate</SPAN>(<SPAN class="type">void</SPAN>)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;0;<BR>&nbsp;&nbsp;<SPAN class="keyword">virtual</SPAN>&nbsp;<SPAN class="type">OZ_PropagatorProfile</SPAN>&nbsp;*&nbsp;<SPAN class="functionname">getProfile</SPAN>(<SPAN class="type">void</SPAN>)&nbsp;<SPAN class="keyword">const</SPAN>&nbsp;=&nbsp;0;<BR>}<BR></PRE></BLOCKQUOTE><P> </P></DIV><P>There are basically three groups of member functions dealing with reflection, memory management, and constraint propagation. Member functions concerned with reflection allow to obtain information about a certain instance of a propagator. For example, this is used to generate a message in case of a top-level failure. </P><DIV class="apropos"><P class="margin"><CODE>getProfile()</CODE></P><P> For each propagator class, one instance of class <CODE>OZ_PropagatorProfile</CODE> is allocated. This class is intended to give the Oz Profiler access to some information about this class, for instance a count of the number of invocations of propagators belonging to this class. This function must return a pointer to this instance, but otherwise the programmer needs not to be concerned about it. Note that for the profile function to be shared for all instances, it has to be declared <CODE>static</CODE>.</P></DIV><P></P><DIV class="apropos"><P class="margin"><CODE>getParameters()</CODE></P><P> The arguments of a propagator are returned by <CODE>getParameters()</CODE> as a list represented as an Oz heap data structure. This is denoted by the return type <CODE>OZ_Term</CODE>. </P></DIV><DIV class="apropos"><P class="margin"><CODE>sizeOf()</CODE></P><P> Memory management of Oz requires to know the size of a propagator. The member function <CODE>sizeOf()</CODE> implements this functionality. Its return type is defined in the standard header <CODE><SPAN class="keyword">&lt;</SPAN>stddef<SPAN class="keyword">.</SPAN>h<SPAN class="keyword">&gt;</SPAN></CODE>. </P></DIV><DIV class="apropos"><P class="margin"><CODE>gCollect()</CODE> and <CODE>sClone()</CODE></P><P> Further, on garbage collection and space cloning references into heap which are held in the state of the propagator (or somehow reachable by a propagator) have to be updated, since items stored on the heap are occasionally moved to a new location. The member functions <CODE>gcollect()</CODE> and <CODE>sClone</CODE> are provided for that purpose. The definition of these functions is identical for most propagators. For an example where the difference of both functions matters see <A href="node8.html#u_advanced.redundant">Section&nbsp;1.7.2</A>. </P></DIV><DIV class="apropos"><P class="margin"><CODE>propagate()</CODE></P><P> The most important member function is <CODE>propagate()</CODE>. It is responsible for the actual constraint propagation and is called by the emulator when the propagator's execution state is switched to <CODE>running</CODE>. The returned value of type <CODE>OZ_Return</CODE> indicates the runtime system the outcome of the propagation performed by <CODE>propagate()</CODE>.</P></DIV><P>The implementation of the addition propagator starts with the definition of the class <CODE>AddProp</CODE>. The definition of the member function <CODE>propagate()</CODE> is explained in <A href="node3.html#u_getting_started.propagation">Section ``The Propagation Part of a Propagator''</A>. </P><BLOCKQUOTE class="linenumbers"><PRE>#ifndef&nbsp;NDEBUG<BR>#include&nbsp;<SPAN class="string">&lt;stdio.h&gt;</SPAN>&nbsp;<BR>#endif&nbsp;<BR>&nbsp;<BR>#include&nbsp;<SPAN class="string">&quot;mozart_cpi.hh&quot;</SPAN>&nbsp;<BR></PRE></BLOCKQUOTE><P> </P><BLOCKQUOTE class="linenumbers"><PRE><SPAN class="keyword">class</SPAN>&nbsp;<SPAN class="type">AddProp</SPAN>&nbsp;:&nbsp;<SPAN class="keyword">public</SPAN>&nbsp;<SPAN class="type">OZ_Propagator</SPAN>&nbsp;{<BR>&nbsp;&nbsp;<SPAN class="keyword">friend</SPAN>&nbsp;<SPAN class="type">OZ_C_proc_interface</SPAN>&nbsp;*<SPAN class="functionname">oz_init_module</SPAN>(<SPAN class="type">void</SPAN>);<BR><SPAN class="keyword">private</SPAN>:<BR>&nbsp;&nbsp;<SPAN class="keyword">static</SPAN>&nbsp;<SPAN class="type">OZ_PropagatorProfile</SPAN>&nbsp;<SPAN class="variablename">profile</SPAN>;<BR>&nbsp;&nbsp;<SPAN class="type">OZ_Term</SPAN>&nbsp;<SPAN class="variablename">_x</SPAN>,&nbsp;<SPAN class="variablename">_y</SPAN>,&nbsp;<SPAN class="variablename">_z</SPAN>;<BR><SPAN class="keyword">public</SPAN>:<BR>&nbsp;&nbsp;<SPAN class="functionname">AddProp</SPAN>(<SPAN class="type">OZ_Term</SPAN>&nbsp;<SPAN class="variablename">a</SPAN>,&nbsp;<SPAN class="type">OZ_Term</SPAN>&nbsp;<SPAN class="variablename">b</SPAN>,&nbsp;<SPAN class="type">OZ_Term</SPAN>&nbsp;<SPAN class="variablename">c</SPAN>)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;:&nbsp;_x(a),&nbsp;_y(b),&nbsp;_z(c)&nbsp;{}<BR>&nbsp;&nbsp;<SPAN class="keyword">virtual</SPAN>&nbsp;<SPAN class="type">OZ_Return</SPAN>&nbsp;<SPAN class="functionname">propagate</SPAN>(<SPAN class="type">void</SPAN>);<BR>&nbsp;<BR>&nbsp;&nbsp;<SPAN class="keyword">virtual</SPAN>&nbsp;<SPAN class="type">size_t</SPAN>&nbsp;<SPAN class="functionname">sizeOf</SPAN>(<SPAN class="type">void</SPAN>)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">return</SPAN>&nbsp;<SPAN class="keyword">sizeof</SPAN>(AddProp);&nbsp;&nbsp;<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;<SPAN class="keyword">virtual</SPAN>&nbsp;<SPAN class="type">void</SPAN>&nbsp;<SPAN class="functionname">gCollect</SPAN>(<SPAN class="type">void</SPAN>)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;OZ_gCollectTerm(_x);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;OZ_gCollectTerm(_y);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;OZ_gCollectTerm(_z);<BR>&nbsp;&nbsp;}&nbsp;&nbsp;<BR>&nbsp;&nbsp;<SPAN class="keyword">virtual</SPAN>&nbsp;<SPAN class="type">void</SPAN>&nbsp;<SPAN class="functionname">sClone</SPAN>(<SPAN class="type">void</SPAN>)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;OZ_sCloneTerm(_x);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;OZ_sCloneTerm(_y);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;OZ_sCloneTerm(_z);<BR>&nbsp;&nbsp;}&nbsp;&nbsp;<BR>&nbsp;&nbsp;<SPAN class="keyword">virtual</SPAN>&nbsp;<SPAN class="type">OZ_Term</SPAN>&nbsp;<SPAN class="functionname">getParameters</SPAN>(<SPAN class="type">void</SPAN>)&nbsp;<SPAN class="keyword">const</SPAN>&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">return</SPAN>&nbsp;OZ_cons(_x,&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OZ_cons(_y,&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OZ_cons(_z,&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OZ_nil())));<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;<SPAN class="keyword">virtual</SPAN>&nbsp;<SPAN class="type">OZ_PropagatorProfile</SPAN>&nbsp;*<SPAN class="functionname">getProfile</SPAN>(<SPAN class="type">void</SPAN>)&nbsp;<SPAN class="keyword">const</SPAN>&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">return</SPAN>&nbsp;&amp;profile;&nbsp;&nbsp;<BR>&nbsp;&nbsp;}<BR>};<BR>&nbsp;<BR><SPAN class="type">OZ_PropagatorProfile</SPAN>&nbsp;<SPAN class="reference">AddProp</SPAN>::<SPAN class="variablename">profile</SPAN>;<BR>&nbsp;<BR></PRE></BLOCKQUOTE><P> The propagator stores in its state, i.&nbsp;e. in its data members, references to the variables it is imposed on (namely <CODE>_x</CODE>, <CODE>_y</CODE> and <CODE>_z</CODE> of type <CODE>OZ_Term</CODE>. The constructor of the class <CODE>AddProp</CODE>, which is invoked by the header function, initialises the data members with the arguments of the corresponding Oz application. The member function <CODE>sizeOf()</CODE> returns the number of bytes occupied by the addition propagator using C/C++'s <CODE>sizeof</CODE> operator. The C<SPAN class="allcaps">PI</SPAN> provides for the functions <CODE>OZ_gCollectTerm()</CODE> and <CODE>OZ_sCloneTerm()</CODE>, which are used for the implemention of the member functions <CODE>gcollect()</CODE> and <CODE>sClone()</CODE>, which apply <CODE>gCollectTerm()</CODE> resp. <CODE>sCloneTerm()</CODE> to all data members of type <CODE>OZ_Term</CODE>. The construction of lists is supported by the interface abstractions <CODE>OZ_cons()</CODE> and <CODE>OZ_nil()</CODE> (see <A href="../foreign/node14.html#section.term_access">Section&nbsp;7.7 of ``Interfacing to C and C++''</A>). The function <CODE>getParameters()</CODE> straightforwardly composes a list containing the references to the arguments hold in the propagator's state. The reason for the friend declaration will become clear in <A href="node3.html#u_getting_started.creating">Section ``Creating a Propagator''</A>.</P><P></P></DIV><DIV id="u_getting_started.propagation"><H4><A name="u_getting_started.propagation">The Propagation Part of a Propagator</A></H4><P>The member function <CODE>propagate()</CODE> implements the algorithm which defines the operational semantics of the propagator, i.&nbsp;e. the amount of constraint propagation achieved at each invocation.</P><P>The algorithm used here rebuilds the domains of the variables always from scratch. Therefore, auxiliary domains for each variable are introduced which are initially empty. For all values of the domains of <IMG alt="x" src="latex4.png"> and <IMG alt="y" src="latex5.png"> it is checked if there is a consistent value in the domain of <IMG alt="z" src="latex22.png">. If so, the values are added to the corresponding auxiliary domains. Finally, the domains of the variables are constrained,i.&nbsp;e. intersected, with the corresponding auxiliary domains. Consequently, the core of the program code consists of two nested loops iterating over all values of the domains of <IMG alt="x" src="latex4.png"> and <IMG alt="y" src="latex5.png">. </P><BLOCKQUOTE class="linenumbers"><PRE>#define&nbsp;<SPAN class="functionname">FailOnEmpty</SPAN>(<SPAN class="variablename">X</SPAN>)&nbsp;<SPAN class="keyword">if</SPAN>((X)&nbsp;==&nbsp;0)&nbsp;<SPAN class="keyword">goto</SPAN>&nbsp;<SPAN class="reference">failure</SPAN>;<BR></PRE></BLOCKQUOTE><P> </P><BLOCKQUOTE class="linenumbers"><PRE><SPAN class="type">OZ_Return</SPAN>&nbsp;<SPAN class="reference">AddProp</SPAN>::<SPAN class="functionname">propagate</SPAN>(<SPAN class="type">void</SPAN>)<BR>{<BR></PRE></BLOCKQUOTE><P> </P><BLOCKQUOTE class="linenumbers"><PRE>&nbsp;&nbsp;<SPAN class="type">OZ_FDIntVar</SPAN>&nbsp;<SPAN class="functionname">x</SPAN>(_x),&nbsp;<SPAN class="functionname">y</SPAN>(_y),&nbsp;<SPAN class="functionname">z</SPAN>(_z);<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;<SPAN class="type">OZ_FiniteDomain</SPAN>&nbsp;<SPAN class="functionname">x_aux</SPAN>(fd_empty),&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="functionname">y_aux</SPAN>(fd_empty),&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="functionname">z_aux</SPAN>(fd_empty);<BR>&nbsp;<BR>&nbsp;&nbsp;<SPAN class="keyword">for</SPAN>&nbsp;(<SPAN class="type">int</SPAN>&nbsp;<SPAN class="variablename">i</SPAN>&nbsp;=&nbsp;x-&gt;getMinElem();&nbsp;i&nbsp;!=&nbsp;-1;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;=&nbsp;x-&gt;getNextLargerElem(i))<BR>&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">for</SPAN>&nbsp;(<SPAN class="type">int</SPAN>&nbsp;<SPAN class="variablename">j</SPAN>&nbsp;=&nbsp;y-&gt;getMinElem();&nbsp;j&nbsp;!=&nbsp;-1;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j&nbsp;=&nbsp;y-&gt;getNextLargerElem(j))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">if</SPAN>&nbsp;(z-&gt;isIn(i&nbsp;+&nbsp;j))&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x_aux&nbsp;+=&nbsp;i;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y_aux&nbsp;+=&nbsp;j;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;z_aux&nbsp;+=&nbsp;(i&nbsp;+&nbsp;j);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;FailOnEmpty(*x&nbsp;&amp;=&nbsp;x_aux);<BR>&nbsp;&nbsp;FailOnEmpty(*y&nbsp;&amp;=&nbsp;y_aux);<BR>&nbsp;&nbsp;FailOnEmpty(*z&nbsp;&amp;=&nbsp;z_aux);<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;<SPAN class="keyword">return</SPAN>&nbsp;(x.leave()&nbsp;|&nbsp;y.leave()&nbsp;|&nbsp;z.leave())&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;?&nbsp;OZ_SLEEP&nbsp;:&nbsp;OZ_ENTAILED;<BR>&nbsp;<BR><SPAN class="reference">failure</SPAN>:&nbsp;&nbsp;<BR>&nbsp;&nbsp;x.fail();<BR>&nbsp;&nbsp;y.fail();<BR>&nbsp;&nbsp;z.fail();<BR>&nbsp;&nbsp;<SPAN class="keyword">return</SPAN>&nbsp;OZ_FAILED;<BR>}<BR>&nbsp;<BR></PRE></BLOCKQUOTE><P> </P><DIV class="apropos"><P class="margin">C<SPAN class="allcaps">PI</SPAN> class <CODE>OZ_FDIntVar</CODE></P><P> A propagator needs direct access to the variables it is imposed on. The interface class <CODE>OZ_FDIntVar</CODE> provides member functions to access variables in the constraint store. The constructor dereferences a variable in the store and stores the dereferenced information in the state of the newly created object. The operators <CODE><SPAN class="keyword">*</SPAN></CODE> and <CODE><SPAN class="keyword">-&gt;</SPAN></CODE> are overloaded to provide direct access to the finite domain of a variable in the store or to invoke member functions of the class <CODE>OZ_FiniteDomain</CODE> (see below). </P></DIV><P></P><DIV class="apropos"><P class="margin">C<SPAN class="allcaps">PI</SPAN> class <CODE>OZ_FiniteDomain</CODE></P><P> The finite domain of a variable is represented by an instance of the class <CODE>OZ_FiniteDomain</CODE>, modifying their value is immediately visible in the constraint store. Calling the constructor with the value <CODE>fd_empty</CODE> creates an empty finite domain, as used for the auxiliary variables here. The operator <CODE><SPAN class="keyword">+</SPAN>=</CODE> adds a value to a domain. The operator <CODE><SPAN class="string">&amp;=</SPAN></CODE> intersects two domains, modifies the domain on the left hand side and returns the size of the intersected domain. The member function <CODE>getMinElem()</CODE> returns the smallest value of the domain and <CODE>getNextLargerElem(i)</CODE> returns the smallest value of the domain larger than <CODE>i</CODE> (both return <CODE><SPAN class="keyword">-</SPAN>1</CODE> when they reach their respective end of the domain). Testing whether a value is contained in a domain or not can be done by the member function <CODE>isIn()</CODE>. </P></DIV><DIV class="apropos"><P class="margin">The implementation</P><P> The implementation of the constraint <IMG alt="x+y=z" src="latex1.png"> proceeds as follows. First the variables in the store are retrieved and stored in the local C/C++ variables <CODE>x</CODE>, <CODE>y</CODE> and <CODE>z</CODE>. The corresponding auxiliary domains are held in the variables <CODE>x_aux</CODE>, <CODE>y_aux</CODE> and <CODE>z_aux</CODE>, which are initialised to empty domains. Two nested for-loops enumerate all possible pairs <IMG alt="(v_x,v_y)" src="latex23.png"> of values of the domains of <IMG alt="x" src="latex4.png"> and <IMG alt="y" src="latex5.png">. Each loop starts from the smallest value of the domain and proceeds until -1 is returned, indicating that there is no larger value. If there is a value <IMG alt="v_z" src="latex24.png"> in the domain of <IMG alt="z" src="latex22.png"> satisfying the relation <IMG alt="v_x + v_y = v_z" src="latex25.png">, these values are added to the appropriate auxiliary domains. After completing the nested loops, the domains of the variables are constrained by intersecting them with the auxiliary domains. </P></DIV><DIV class="apropos"><P class="margin"><CODE>FailOnEmpty()</CODE></P><P> The macro <CODE>FailOnEmpty()</CODE> branches to the label <CODE>failure</CODE> if its argument results in the value 0. Thereby, constraining the domain of a variable to an empty domain causes the execution to branch to label <CODE>failure</CODE> and eventually to return <CODE>OZ_FAILED</CODE> to the emulator. The return value of the member function <CODE>leave()</CODE> of class <CODE>OZ_FDIntVar</CODE> is used to decide whether the propagator returns <CODE>OZ_SLEEP</CODE> or <CODE>OZ_ENTAILED</CODE>. The return value <CODE>OZ_ENTAILED</CODE> indicates entailment and is returned if all variable's domains are singletons. Otherwise, <CODE>OZ_SLEEP</CODE> is returned and the propagator is resumed when at least one of its variables is constrained again. </P></DIV><P>Before leaving <CODE>propagate()</CODE>, the member function <CODE>leave()</CODE> has to be called. If the variable's domain has been constrained by the propagator, it causes the scheduler to switch all propagators waiting for further constraints on that variable to become <CODE>runnable</CODE>. The return value of <CODE>leave</CODE> is 0 if the domain became a singleton, otherwise 1. This information is used to decide whether a propagator is entailed or not. In case the propagator encounters an empty domain or any other inconsistency, the member function <CODE><SPAN class="keyword">fail</SPAN>()</CODE> has to be called to do some cleanups before <CODE>propagate()</CODE> is left. </P></DIV><DIV id="u_getting_started.creating"><H4><A name="u_getting_started.creating">Creating a Propagator</A></H4><DIV class="apropos"><P class="margin">The header function</P><P> Before a propagator can be created and introduced to the emulator, its variables must be sufficiently constrained, e.g. the variables must be constrained to finite domains. In case, only a subset of variables is sufficiently constrained, the computation will suspend and resume again when more constraints become available. This is checked by the header function, which is called by the runtime system, when an appropriately connected Oz abstraction is applied. For our example, this function is called <CODE>fd_add</CODE>. </P></DIV><DIV class="apropos"><P class="margin">Determining when to resume a propagator</P><P> Further, when a propagator is imposed on a variable, it has to be determined which changes to the domain resume the propagator again. The alternatives are to resume a propagator if the variable's domain becomes a singleton, the bounds are narrowed or some value is removed from the domain. </P></DIV><P> The macros <CODE>OZ_BI_define</CODE> and <CODE>OZ_BI_end</CODE> are provided to allow the implementation of C/C++ functions which are compliant with the calling conventions of Oz's emulator. </P><P> The first argument of the macro <CODE>OZ_BI_define</CODE> defines the name of the function, the second argument the number of input arguments of type <CODE>OZ_Term</CODE>, and the third argument the number of output arguments of type <CODE>OZ_Term</CODE> (for a propagator this will always be 0). The macro <CODE>OZ_args</CODE> provides access to the actual argument. The name of the function has to obey certain rules to be compatible with the module <CODE>Foreign</CODE> which enables linking object files to a running Oz runtime system. The definition of the macro <CODE>OZ_EXPECTED_TYPE</CODE> is explained in <A href="../cpiref/node2.html#expect.macros">Section&nbsp;1.2.6 of ``The Mozart Constraint Extensions Reference''</A>. </P><BLOCKQUOTE class="linenumbers"><PRE><SPAN class="functionname">OZ_BI_define</SPAN>(fd_add,&nbsp;3,&nbsp;0)<BR>{<BR>&nbsp;&nbsp;OZ_EXPECTED_TYPE(OZ_EM_FD<SPAN class="string">&quot;,&quot;</SPAN>OZ_EM_FD<SPAN class="string">&quot;,&quot;</SPAN>OZ_EM_FD);<BR>&nbsp;<BR>&nbsp;&nbsp;<SPAN class="type">OZ_Expect</SPAN>&nbsp;<SPAN class="variablename">pe</SPAN>;<BR>&nbsp;<BR>&nbsp;&nbsp;OZ_EXPECT(pe,&nbsp;0,&nbsp;expectIntVar);<BR>&nbsp;&nbsp;OZ_EXPECT(pe,&nbsp;1,&nbsp;expectIntVar);<BR>&nbsp;&nbsp;OZ_EXPECT(pe,&nbsp;2,&nbsp;expectIntVar);<BR>&nbsp;<BR>&nbsp;&nbsp;<SPAN class="keyword">return</SPAN>&nbsp;pe.impose(<SPAN class="keyword">new</SPAN>&nbsp;<SPAN class="type">AddProp</SPAN>(OZ_in(0),&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OZ_in(1),&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OZ_in(2)));<BR>}<BR>OZ_BI_end<BR></PRE></BLOCKQUOTE><P> </P><DIV class="apropos"><P class="margin">Using <CODE>OZ_EXPECT</CODE></P><P> The macro <CODE>OZ_EXPECT</CODE> ensures that incompatible constraints on the propagator's parameters lead to failure and insufficient constraints cause the execution to be suspended until more constraints become known. An object of class <CODE>OZ_Expect</CODE> collects in its state all variables the propagator is to be imposed on. Such an object is at the first argument position of <CODE>OZ_EXPECT</CODE>. The second argument of <CODE>OZ_EXPECT</CODE> determines which argument of <CODE>fd_add</CODE> shall be checked. The member function <CODE>expectIntVar()</CODE> of class <CODE>OZ_Expect</CODE> expects a variable to be already constrained to a finite domain. If a variable is sufficiently constrained, it is stored in the state of the object <CODE>pe</CODE>. The second argument of <CODE>expectIntVar</CODE> is used to determine what kind of domain pruning causes a propagator to be resumed. Its default value is <CODE>fd_prop_any</CODE>, i.&nbsp;e. a propagator is resumed on any pruning of the domain. For further details see <A href="node5.html#u_nesting">Section&nbsp;1.4</A>. </P></DIV><DIV class="apropos"><P class="margin">Creation of a propagator</P><P> Finally, the actual propagator is created by calling its constructor via the application of the <CODE>new</CODE> operator. The reference to the newly created propagator is passed as argument to <CODE>impose()</CODE>, a member function of <CODE>OZ_Expect</CODE>, which executes the <CODE>propagate()</CODE> method and introduces the propagator to the emulator. </P></DIV><DIV class="apropos"><P class="margin">Connecting Propagators and Oz Code</P><P> Propagators are connected with Mozart Oz 3 as native functors according to <A href="../apptut/node20.html#section.counter.global.compilation.deployment">Section&nbsp;15.3 of ``Application Programming''</A>. To enable that one has to define a function <CODE>oz_init_module</CODE>. </P><BLOCKQUOTE><PRE>&nbsp;<BR>OZ_BI_proto(fd_add);<BR>&nbsp;<BR><SPAN class="type">OZ_C_proc_interface</SPAN>&nbsp;*<SPAN class="functionname">oz_init_module</SPAN>(<SPAN class="type">void</SPAN>)<BR>{<BR>&nbsp;&nbsp;<SPAN class="keyword">static</SPAN>&nbsp;<SPAN class="type">OZ_C_proc_interface</SPAN>&nbsp;<SPAN class="variablename">i_table</SPAN>[]&nbsp;=&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<SPAN class="string">&quot;add&quot;</SPAN>,&nbsp;3,&nbsp;0,&nbsp;fd_add},<BR>&nbsp;&nbsp;&nbsp;&nbsp;{0,0,0,0}<BR>&nbsp;&nbsp;};<BR>&nbsp;<BR>&nbsp;&nbsp;<SPAN class="reference">AddProp</SPAN>::profile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;<SPAN class="string">&quot;addition/3&quot;</SPAN>;<BR>&nbsp;<BR>&nbsp;&nbsp;printf(<SPAN class="string">&quot;addition&nbsp;propagator&nbsp;loaded\n&quot;</SPAN>);<BR>&nbsp;&nbsp;<SPAN class="keyword">return</SPAN>&nbsp;i_table;<BR>}<BR>&nbsp;<BR></PRE></BLOCKQUOTE><P> The line <CODE>AddProp<SPAN class="keyword">::</SPAN>profile&nbsp;=&nbsp;<SPAN class="string">&quot;addition/3&quot;</SPAN>;</CODE> assigns explicitly the name <CODE><SPAN class="string">&quot;addition/3&quot;</SPAN></CODE> to the propagator. The default name is <CODE><SPAN class="string">&quot;&lt;anonymous&nbsp;propagator&gt;&quot;</SPAN></CODE>.</P></DIV><P>Before a native functor can be loaded it must be compiled according to <A href="../apptut/node20.html#section.counter.global.compilation">Section&nbsp;15.2 of ``Application Programming''</A>. Supposing the C/C++ code is stored in the file <CODE>ex_a<SPAN class="keyword">.</SPAN>cc</CODE>, then the following lines create the object file. </P><BLOCKQUOTE class="code"><CODE>oztool&nbsp;c++&nbsp;-c&nbsp;ex_a.cc&nbsp;-o&nbsp;ex_a.o<BR>oztool&nbsp;ld&nbsp;&nbsp;-o&nbsp;ex_a.so-linux-i486&nbsp;ex_a.o&nbsp;&nbsp;</CODE></BLOCKQUOTE><P> </P><P>The Oz code below loads the object file <CODE>ex_a<SPAN class="keyword">.</SPAN>so<SPAN class="keyword">-</SPAN>linux<SPAN class="keyword">-</SPAN>i486</CODE> and makes the Oz abstraction <CODE>FD_PROP<SPAN class="keyword">.</SPAN>add</CODE> available. The procedure <CODE>FD_PROP<SPAN class="keyword">.</SPAN>add</CODE> takes 3 arguments and imposes the addition propagator implemented in the sections before. </P><BLOCKQUOTE class="linenumbers"><PRE><SPAN class="keyword">declare</SPAN>&nbsp;FD_PROP&nbsp;&nbsp;<BR><SPAN class="keyword">local</SPAN>&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;FD_PROP_O&nbsp;=&nbsp;{{New&nbsp;Module<SPAN class="keyword">.</SPAN>manager&nbsp;init}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;link(url:&nbsp;<SPAN class="string">'ex_a.so{native}'</SPAN>&nbsp;$)}<BR><SPAN class="keyword">in</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;FD_PROP&nbsp;=&nbsp;fd(add:&nbsp;FD_PROP_O<SPAN class="keyword">.</SPAN>add)<BR>&nbsp;&nbsp;&nbsp;{Browse&nbsp;FD_PROP}<BR><SPAN class="keyword">end</SPAN>&nbsp;&nbsp;<BR></PRE></BLOCKQUOTE><P> After feeding in the above Oz code the addition propagator is available and can be used. To do so feed the following code in line by line. The results are shown in the Oz browser (shown in comments appended to lines). </P><BLOCKQUOTE class="linenumbers"><PRE><SPAN class="keyword">declare</SPAN>&nbsp;X&nbsp;Y&nbsp;Z&nbsp;<SPAN class="keyword">in</SPAN>&nbsp;&nbsp;<BR>{Browse&nbsp;[X&nbsp;Y&nbsp;Z]}&nbsp;&nbsp;&nbsp;&nbsp;%&nbsp;<SPAN class="comment">[X&nbsp;Y&nbsp;Z]<BR></SPAN>&nbsp;<BR>[X&nbsp;Y&nbsp;Z]&nbsp;<SPAN class="keyword">:::</SPAN>&nbsp;0<SPAN class="keyword">#</SPAN>10&nbsp;&nbsp;&nbsp;&nbsp;%&nbsp;&nbsp;<SPAN class="comment">[X{0#10}&nbsp;Y{0#10}&nbsp;Z{0#10}]<BR></SPAN>&nbsp;<BR>{FD_PROP<SPAN class="keyword">.</SPAN>add&nbsp;X&nbsp;Y&nbsp;Z}&nbsp;%&nbsp;&nbsp;<SPAN class="comment">[X{0#10}&nbsp;Y{0#10}&nbsp;Z{0#10}]<BR></SPAN>&nbsp;<BR>X&nbsp;<SPAN class="keyword">::</SPAN>&nbsp;[1&nbsp;3&nbsp;5&nbsp;7&nbsp;9]&nbsp;&nbsp;&nbsp;&nbsp;%&nbsp;<SPAN class="comment">[X{1&nbsp;3&nbsp;5&nbsp;7&nbsp;9}&nbsp;Y{0#9}&nbsp;Z{1#10}]<BR></SPAN>Y&nbsp;<SPAN class="keyword">::</SPAN>&nbsp;[1&nbsp;3&nbsp;5&nbsp;7&nbsp;9]&nbsp;&nbsp;&nbsp;&nbsp;%&nbsp;<SPAN class="comment">[X{1&nbsp;3&nbsp;5&nbsp;7&nbsp;9}&nbsp;Y{1&nbsp;3&nbsp;5&nbsp;7&nbsp;9}<BR></SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%&nbsp;&nbsp;<SPAN class="comment">Z{2&nbsp;4&nbsp;6&nbsp;8&nbsp;10}]<BR></SPAN>Y&nbsp;<SPAN class="keyword">&lt;:</SPAN>&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%&nbsp;<SPAN class="comment">[X{1&nbsp;3&nbsp;5&nbsp;7&nbsp;9}&nbsp;Y{1&nbsp;3}<BR></SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%&nbsp;&nbsp;<SPAN class="comment">Z{2&nbsp;4&nbsp;6&nbsp;8&nbsp;10}]<BR></SPAN>Y&nbsp;<SPAN class="keyword">\=:</SPAN>&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%&nbsp;<SPAN class="comment">[X{1&nbsp;3&nbsp;5&nbsp;7&nbsp;9}&nbsp;1&nbsp;Z{2&nbsp;4&nbsp;6&nbsp;8&nbsp;10}]<BR></SPAN></PRE></BLOCKQUOTE><P> </P><DIV class="apropos"><P class="margin">Troubleshooting</P><P> </P></DIV><P> Debugging a propagator is usually done by <CODE>gdb</CODE> <A href="bib.html#gdb">[RMS92]</A> in conjunction with <CODE>emacs</CODE> <A href="bib.html#stallman91">[Sta91]</A>. The Oz Programming Interface provides adequate means to support debugging based on these two tools. We refer the reader to <A href="../opi/node10.html#section.intro.gdb">Section&nbsp;B.3 of ``The Oz Programming Interface''</A> for details. </P></DIV></DIV></DIV><TABLE align="center" border="0" cellpadding="6" cellspacing="6" class="nav"><TR bgcolor="#DDDDDD"><TD><A href="node2.html#u_basic_concepts">&lt;&lt; Prev</A></TD><TD><A href="node1.html">- Up -</A></TD><TD><A href="node4.html#u_replacing">Next &gt;&gt;</A></TD></TR></TABLE><HR><ADDRESS><A href="http://www.ps.uni-sb.de/~tmueller/">Tobias&nbsp;Müller</A><BR><SPAN class="version">Version 1.4.0 (20110908185330)</SPAN></ADDRESS></BODY></HTML>