Generated on Mon Aug 25 11:35:34 2008 for Gecode by doxygen 1.5.6

support.icc

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Patrick Pekczynski <pekczynski@ps.uni-sb.de>
00005  *
00006  *  Copyright:
00007  *     Patrick Pekczynski, 2006
00008  *
00009  *  Last modified:
00010  *     $Date: 2008-02-06 18:48:22 +0100 (Wed, 06 Feb 2008) $ by $Author: schulte $
00011  *     $Revision: 6102 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00035  *
00036  */
00037 
00038 namespace Gecode { namespace CpltSet {
00039 
00041   forceinline void
00042   testConsistency(const IntSet& glb, const IntSet& lub,
00043                   const int cardMin, const int cardMax,
00044                   const char* location) {
00045 
00046     bool glbNonZero = glb.size() > 0;
00047     bool lubNonZero = lub.size() > 0;
00048 
00049     if (glbNonZero) {
00050       int  glbMin = glb.min();
00051       int  glbMax = glb.max();
00052       if (
00053           !lubNonZero ||
00054           (glbMin > glbMax)
00055           )
00056         throw CpltSet::VariableFailedDomain(location);
00057 
00058       if (
00059           (glbMin < Set::Limits::min) || 
00060           (glbMax > Set::Limits::max)
00061           ) 
00062         throw CpltSet::VariableOutOfRangeDomain(location);
00063       
00064       int  lubMin = lub.min();
00065       int  lubMax = lub.max();
00066       if (
00067           (glbMin < lubMin || glbMin > lubMax) ||
00068           (glbMax > lubMax || glbMax < lubMin)
00069           )
00070         throw CpltSet::VariableFailedDomain(location);
00071     }
00072 
00073     if (lubNonZero) {
00074       int  lubMin = lub.min();
00075       int  lubMax = lub.max();
00076       if (
00077           (lubMin < Set::Limits::min) || 
00078           (lubMax > Set::Limits::max)
00079          )
00080         throw CpltSet::VariableOutOfRangeDomain(location);
00081 
00082       if (lubMin > lubMax)
00083       throw CpltSet::VariableFailedDomain(location);
00084     }
00085 
00086     if (cardMax < 0)    
00087       throw CpltSet::VariableFailedDomain(location);
00088 
00089     if ((unsigned int) cardMax > Set::Limits::card)
00090       throw CpltSet::VariableOutOfRangeCardinality(location);
00091 
00092     if ( 
00093         (cardMin > cardMax) ||
00094         (cardMin < 0)
00095         )
00096       throw CpltSet::VariableFailedDomain(location);
00097     return;
00098   }
00099 
00100   template <class View>
00101   void 
00102   variableorder(ViewArray<View>& x) {
00103     unsigned int var_in_tab = manager.allocated();
00104 
00105     unsigned int min_offset = x[0].offset();
00106     unsigned int max_width  = x[0].tableWidth();
00107     for (int i = 0; i < x.size(); i++) {
00108       if (x[i].offset() < min_offset) {
00109         min_offset = x[i].offset();
00110       }
00111       if (x[i].tableWidth() > max_width) {
00112         max_width = x[i].tableWidth();
00113       }
00114     }
00115 
00116     // constraint order as specified by Hawkins, Lagoon and Stuckey
00117     GECODE_AUTOARRAY(int, hls_order, var_in_tab);
00118 
00119     // we do not care about variables 
00120     // that are not in the scope of the constraint
00121     int c = 0;
00122     for (unsigned int i = 0; i < min_offset; i++, c++) {
00123       hls_order[i] = i;
00124     }
00125 
00126     // ordering those that lie in the scope
00127     for (unsigned int f = 0; f < max_width; f++) {
00128       for (int i = 0; i < x.size(); i++) {
00129         int xo = x[i].offset();
00130         int xw = x[i].tableWidth();
00131         int cur= xo + f;
00132         if (cur < xo + xw) {
00133           hls_order[c] = cur;
00134           c++;
00135         }
00136       }
00137     }
00138 
00139     // IMPORTANT DO NOT FORGET REMAINING LARGER VARIABLES
00140     for (unsigned int i = c; i < var_in_tab; i++, c++) {
00141       hls_order[i] = i;
00142     }   
00143     
00144     manager.setorder(&hls_order[0]);
00145   }
00146 
00147   template <class View, class View1>
00148   void 
00149   variableorder(ViewArray<View>& x, ViewArray<View1>& y) {
00150     unsigned int var_in_tab = manager.allocated();
00151 
00152     unsigned int min_offset = x[0].offset();
00153     unsigned int max_width  = x[0].tableWidth();
00154     for (int i = 0; i < x.size(); i++) {
00155       if (x[i].offset() < min_offset) {
00156         min_offset = x[i].offset();
00157       }
00158       if (x[i].tableWidth() > max_width) {
00159         max_width = x[i].tableWidth();
00160       }
00161     }
00162 
00163     // constraint order as specified by Hawkins, Lagoon and Stuckey
00164     GECODE_AUTOARRAY(int, hls_order, var_in_tab);
00165 
00166     // we do not care about variables 
00167     // that are not in the scope of the constraint
00168     int c = 0;
00169     for (unsigned int i = 0; i < min_offset; i++, c++) {
00170       hls_order[i] = i;
00171     }
00172 
00173     // ordering those that lie in the scope
00174     for (unsigned int f = 0; f < max_width; f++) {
00175       for (int i = 0; i < x.size(); i++) {
00176         int xo = x[i].offset();
00177         int xw = x[i].tableWidth();
00178         int cur= xo + f;
00179         if (cur < xo + xw) {
00180           hls_order[c] = cur;
00181           c++;
00182         }
00183       }
00184       // INVARIANT: Here we assume that variables of the same array
00185       //            have the same initial values for min and max of the set 
00186       //            bounds
00187       // invariant new arrays have subranges of old arrays
00188       for (int i = 0; i < y.size(); i++) {
00189         if ( (x[0].initialLubMin() + (int) f >= y[i].initialLubMin()) &&
00190              (x[0].initialLubMin() + (int) f <= y[i].initialLubMax())) {
00191           int xyshift = y[i].initialLubMin()  - x[0].initialLubMin();
00192           int yo = y[i].offset();
00193           int yw = y[i].tableWidth();
00194           int cur= yo + f - xyshift;
00195           if (cur <= yo + yw) {
00196             hls_order[c] = cur;
00197             c++;
00198           }
00199         }
00200       }
00201     }
00202 
00203     // Order remaining variables
00204     for (unsigned int i = c; i < var_in_tab; i++, c++) {
00205       hls_order[i] = i;
00206     }   
00207 
00208     manager.setorder(&hls_order[0]);
00209   }
00210 
00212   GECODE_CPLTSET_EXPORT void conv_hull(bdd& robdd, bdd& hull);
00213 
00215   GECODE_CPLTSET_EXPORT bdd bdd_vars(bdd& domain);
00216 
00217 
00219   GECODE_CPLTSET_EXPORT bdd 
00220   cardeq(int offset, int c, int n, int r);
00221 
00223   GECODE_CPLTSET_EXPORT bdd 
00224   cardlqgq(int offset, int cl, int cr, int n, int r);
00225 
00227   GECODE_CPLTSET_EXPORT bdd 
00228   cardcheck(int xtab, int offset, int cl, int cr);
00229 
00230   // EXTENDED CARDINALITY FOR REPLACING INTERMEDIATE VARIABLES
00231 
00233   template <class I, class View0, class View1>
00234   bdd 
00235   extcardeq(Gecode::Iter::Ranges::ValCache<I>& inter, 
00236             View0& x, View1& y, unsigned int c, int n, int) {
00237     int xmin = x.initialLubMin();
00238     int ymin = y.initialLubMin();
00239 
00240     GECODE_AUTOARRAY(bdd, layer, n);
00241     for (int i = n; i--;) 
00242       layer[i].init();
00243 
00244     // build nodes for lowest layer
00245     layer[0] = bdd_true();
00246     inter.last();
00247     for (unsigned int i = 1; i <= c; i++) {
00248       int k = inter.min();
00249       layer[i].init();
00250       layer[i] = x.element(k - xmin);
00251       layer[i] &= y.element(k - ymin);
00252     }
00253 
00254     // connect nodes in lowest layer
00255     for (int i = 1; i < n; i++) {
00256       layer[i] = manager.ite(layer[i], layer[i - 1], bdd_false());
00257     }
00258 
00259     inter.last();
00260 
00261     // build the remaining layers on top
00262     for (; inter(); --inter) {
00263       unsigned int pos = inter.index();
00264       for (int i = 0; i < n; i++) {
00265         int col = inter.min();
00266         bdd t = bdd_true();
00267         if (i == 0) {
00268           t = bdd_false();
00269         } else {
00270           t = layer[i-1]; 
00271         }
00272         bdd both = manager.ite(y.element(col - ymin), t,layer[i]);
00273         layer[i] = manager.ite(x.element(col - xmin), both ,layer[i]);
00274         --inter;
00275         if (!inter()) { break;}
00276       }
00277       if (!inter()) { break;}
00278       inter.index(pos);
00279     }
00280     return layer[n - 1];
00281   }
00282 
00283  
00285   template <class I, class View0, class View1>
00286   bdd 
00287   extcardlqgq(Gecode::Iter::Ranges::ValCache<I>& inter, View0& x, View1& y, 
00288               unsigned int cl, unsigned int cr, int n, int r) {
00289     GECODE_AUTOARRAY(bdd, layer, n);
00290     for (int i = n; i--;) 
00291       layer[i].init();
00292 
00293     // creates TOP v(c) v(c-1) ... v(c - cl + 1)
00294     layer[n - cl - 1] = bdd_true();
00295     
00296     inter.last();
00297 
00298     int k    = inter.min();
00299     int xmin = x.initialLubMin();
00300     int ymin = y.initialLubMin();
00301 
00302     // build nodes for lowest layer
00303     for (int i = n - cl ; i < n; i++, --inter) {
00304       k    = inter.min();
00305       bdd both = manager.ite(y.element(k - ymin), layer[i - 1], bdd_false());
00306       layer[i] = manager.ite(x.element(k - xmin), both, bdd_false());
00307     }
00308 
00309     // start with a shift and build layers up to the connection layer
00310     inter.last();
00311     --inter;
00312 
00313     // IMPORTANT we have to argue about the intersection cache like
00314     // an array with index acces k = kth range in the cache
00315     // hence we need an additional function that returns the index c
00316     // of the cache iterator
00317 
00318     for (; inter(); --inter) {
00319       unsigned int pos = inter.index(); // save position of k
00320       // cl < cr <= tab  ==> n - cl > 0 
00321       for (int i = n - cl; i < n; i++) { 
00322         int col = inter.min();
00323         bdd t = layer[i-1]; 
00324         bdd both = manager.ite(y.element(col - ymin), t, layer[i]);
00325         layer[i] = manager.ite(x.element(col - xmin), both, layer[i]);
00326         --inter;
00327         if ((int) inter.index() + 1 < r + 1 - (int) cr) { 
00328           inter.finish(); break;
00329         }
00330       }
00331       if (!inter()) break;
00332       inter.index(pos);     
00333     }
00334 
00335     if ((int) cr == r + 1) { 
00336       // max card equals table width, all elements allowed
00337       return layer[n - 1];
00338     }
00339     
00340     if ((int) cr == r) {
00341       // only one single layer
00342       inter.last();
00343       int col  = inter.min();
00344       {
00345         bdd t = bdd_true();
00346         bdd f = bdd_true();
00347         bdd zerot = bdd_false();
00348         bdd zerof = t;
00349         for (int i = 0; i < n; i++) {
00350           col  = inter.min();
00351           if (i == 0) {
00352             t = zerot;
00353             f = zerof;
00354           } else {
00355             t = layer[i-1];
00356             if (i > n - (int) cl - 1) { // connect lower layer
00357               f = layer[i];
00358             }
00359           }
00360           bdd both = manager.ite(y.element(col - ymin), t ,f);
00361           layer[i] = manager.ite(x.element(col - xmin), both ,f);
00362           --inter;
00363           if (!inter()) { break;}
00364         }
00365       }
00366       return layer[n- 1];
00367     }
00368   
00369     inter.last();
00370     // connection layer between cl and cr
00371     {
00372       bdd t = bdd_true();
00373       bdd f = bdd_true();
00374       for (int i = 0; i < n; i++) {
00375         int col = inter.min();
00376         if (i == 0) {
00377           t = bdd_false();
00378         } else {
00379           t = layer[i-1];
00380           // NOTE: ONLY CONNECT if cl > 0
00381           if (i > n - (int) cl - 1 && cl > 0) { // connect lower layer
00382             f = layer[i];
00383           }
00384         }
00385         bdd both = manager.ite(y.element(col - ymin), t ,f);
00386         layer[i] = manager.ite(x.element(col - xmin), both ,f);
00387         --inter;
00388         if (!inter()) { break;}
00389       }
00390     }
00391 
00392     // the remaining layers for cr
00393     inter.last();
00394     --inter;
00395     for (; inter(); --inter) {
00396       unsigned int pos = inter.index();
00397       for (int i = 0; i < n; i++) {
00398         int col  = inter.min();
00399         bdd t = bdd_true();
00400         if (i == 0) {
00401           t = bdd_false();
00402         } else {
00403           t = layer[i-1]; 
00404         }
00405         // i guess here we do a little too much
00406         bdd both = y.element(col - ymin) & x.element(col - xmin);
00407         layer[i] = manager.ite(both, t, layer[i]);
00408 
00409         --inter;
00410         if (!inter()) { 
00411           break;
00412         }
00413       }
00414       if (!inter()) { 
00415         break;
00416       }
00417       inter.index(pos);
00418     }
00419     
00420     return layer[n - 1];
00421   }
00422   
00424   template <class View0, class View1>
00425   bdd 
00426   extcardcheck(View0& x, View1& y, unsigned int cl, unsigned int cr) {
00427     // Ad 2)
00428     // we need manager and variable offset for the bddtable
00429     // because we do not want to rewrite the code for the simple checks
00430     // everytime
00431 
00432     // Ad 3) 
00433     // the same extensions for the respective proper cardinality functions
00434   
00435     // Compute the intersection of x and y  and bring it into a data structure
00436     // where iteration may start with the greatest element of the intersection
00437     Set::LubRanges<View0> lubx(x);
00438     Set::LubRanges<View1> luby(y);
00439     // common values
00440     Gecode::Iter::Ranges::Inter<Set::LubRanges<View0>, Set::LubRanges<View1> > 
00441       common(lubx, luby);
00442     // get it cached
00443     Gecode::Iter::Ranges::ToValues<
00444       Gecode::Iter::Ranges::Inter<Set::LubRanges<View0>,
00445         Set::LubRanges<View1> > > values(common);
00446 
00447     Gecode::Iter::Ranges::ValCache<
00448       Gecode::Iter::Ranges::ToValues<
00449         Gecode::Iter::Ranges::Inter<Set::LubRanges<View0>, 
00450           Set::LubRanges<View1> > > > inter(values);
00451 
00452     // compute the size of the intersection
00453     unsigned int isize = inter.size();
00454 
00455     if (cr > isize) { 
00456       cr = isize;
00457     }
00458     int r = isize - 1; // rightmost bit in bitvector
00459     int n = cr + 1; // layer size
00460     if (cl > isize || cl > cr) { // inconsistent cardinality
00461       return bdd_false();
00462     }
00463 
00464     if (cr == 0) {    // cl <= cr
00465       // build the emptyset
00466       bdd empty = bdd_true();
00467       for (; inter(); ++inter) {
00468         int v = inter.min();
00469         assert(v >= x.initialLubMin());
00470         assert(v <= x.initialLubMax());
00471         assert(v >= y.initialLubMin());
00472         assert(v <= y.initialLubMax());
00473         empty &= (x.elementNeg(v - x.initialLubMin()) &
00474                   y.elementNeg(v - y.initialLubMin()));
00475       }
00476       return empty;
00477     }
00478   
00479     if (cl == cr) {
00480       if (cr == isize) {
00481         // build the full set
00482         bdd full = bdd_true();
00483         for (; inter(); ++inter) {
00484           int v = inter.min();
00485           assert(v >= x.initialLubMin());
00486           assert(v <= x.initialLubMax());
00487           assert(v >= y.initialLubMin());
00488           assert(v <= y.initialLubMax());
00489           full &= (x.element(v - x.initialLubMin()) &
00490                    y.element(v - y.initialLubMin()));
00491         }
00492         return full;
00493       } else {
00494         return extcardeq(inter, x, y, cr, n, r);
00495       }
00496     }
00497 
00498     // cl < cr
00499     if (cr == isize) {
00500       if (cl == 0) {   // no cardinality restriction
00501         return bdd_true();
00502       }
00503     }
00504     return extcardlqgq(inter, x, y, cl, cr, n, r);
00505   }
00506 
00507 
00508   // extcard with const intset
00509   template <class I>
00510   bdd 
00511   cardConst(int, int xoff, int xmin, int cl, int cr, I& is) {
00512     // Invariant: We require that the IntSet provided is a subset of the 
00513     // variable range
00514     Gecode::Iter::Ranges::ToValues<I> ir(is);
00515     Gecode::Iter::Ranges::ValCache<Gecode::Iter::Ranges::ToValues<I> > inter(ir);
00516 
00517     int r = inter.size() - 1;    
00518     int n = cr + 1;
00519 
00520     GECODE_AUTOARRAY(bdd, layer, n);
00521     // the use of autoarray now requires explicit initialization
00522     // otherwise the bdd nodes are not known in the global table
00523     for (int i = n; i--;) 
00524       layer[i].init();
00525 
00526     // creates TOP v(c) v(c-1) ... v(c - cl + 1)
00527     layer[n - cl - 1] = bdd_true();
00528     
00529     inter.last();
00530 
00531     int k    = inter.min();
00532 
00533     // build nodes for lowest layer
00534     for (int i = n - cl ; i < n; i++, --inter) {
00535       k    = inter.min();
00536       layer[i] = manager.ite(manager.bddpos(xoff + k - xmin), layer[i - 1], 
00537                              bdd_false());
00538     }
00539 
00540     // start with a shift and build layers up to the connection layer
00541     inter.last();
00542     --inter;
00543 
00544     for (; inter(); --inter) {
00545       // save position of k
00546       unsigned int pos = inter.index(); 
00547 
00548       // cl < cr <= tab  ==> n - cl > 0 
00549       for (int i = n - cl; i < n; i++) { 
00550         int col = inter.min();
00551         bdd t = layer[i-1]; 
00552         layer[i] = manager.ite(manager.bddpos(xoff + col - xmin), t, 
00553                                layer[i]);
00554         --inter;
00555         if ((int) inter.index() + 1 < r + 1 - (int) cr) { 
00556           inter.finish(); break;
00557         }
00558       }
00559       if (!inter()) break;
00560       inter.index(pos);     
00561     }
00562 
00563     if ((int) cr == r + 1) { 
00564       // max card equals table width, all elements allowed
00565       return layer[n - 1];
00566     }
00567     
00568     if ((int) cr == r) {
00569       // only one single layer
00570       inter.last();
00571       int col  = inter.min();
00572       {
00573         bdd t = bdd_true();
00574         bdd f = bdd_true();
00575         bdd zerot = bdd_false();
00576         bdd zerof = t;
00577         for (int i = 0; i < n; i++) {
00578           col  = inter.min();
00579           if (i == 0) {
00580             t = zerot;
00581             f = zerof;
00582           } else {
00583             t = layer[i-1];
00584             if (i > n - (int) cl - 1) { // connect lower layer
00585               f = layer[i];
00586             }
00587           }
00588           layer[i] = manager.ite(manager.bddpos(xoff + col - xmin), t ,f);
00589           --inter;
00590           if (!inter()) { break;}
00591         }
00592       }
00593       return layer[n- 1];
00594     }
00595   
00596     inter.last();
00597     // connection layer between cl and cr
00598     {
00599       bdd t = bdd_true();
00600       bdd f = bdd_true();
00601       for (int i = 0; i < n; i++) {
00602         int col = inter.min();
00603         if (i == 0) {
00604           t = bdd_false();
00605         } else {
00606           t = layer[i-1];
00607           // NOTE: ONLY CONNECT if cl > 0
00608           if (i > n - (int) cl - 1 && cl > 0) { // connect lower layer
00609             f = layer[i];
00610           }
00611         }
00612         layer[i] = manager.ite(manager.bddpos(xoff + col - xmin), t ,f);
00613         --inter;
00614         if (!inter()) { break;}
00615       }
00616     }
00617 
00618     // the remaining layers for cr
00619     inter.last();
00620     --inter;
00621     for (; inter(); --inter) {
00622       unsigned int pos = inter.index();
00623       for (int i = 0; i < n; i++) {
00624         int col  = inter.min();
00625         bdd t = bdd_true();
00626         if (i == 0) {
00627           t = bdd_false();
00628         } else {
00629           t = layer[i-1]; 
00630         }
00631         layer[i] = manager.ite(manager.bddpos(xoff + col - xmin), t,  
00632                                layer[i]);
00633         --inter;
00634         if (!inter()) { 
00635           break;
00636         }
00637       }
00638       if (!inter()) { 
00639         break;
00640       }
00641       inter.index(pos);
00642     }
00643 
00644     return layer[n - 1];
00645   }
00646 
00647   // mark all nodes in the dqueue
00648   GECODE_CPLTSET_EXPORT void
00649   extcache_mark(SharedArray<bdd>& nodes, 
00650                 int n, int& l, int& r, int& markref);
00651 
00652   // unmark all nodes in the dqueue
00653   GECODE_CPLTSET_EXPORT void
00654   extcache_unmark(SharedArray<bdd>& nodes, 
00655                   int n, int& l, int& r, int& markref);
00656 
00657   // iterate to the next level of nodes
00658   GECODE_CPLTSET_EXPORT void 
00659   extcardbounds(int& markref, bdd& c, int& n, int& l, int& r,
00660                 bool& singleton, int& _level, 
00661                 SharedArray<bdd>& nodes, 
00662                 int& curmin, int& curmax, Gecode::IntSet& out);
00663 
00664 
00665   GECODE_CPLTSET_EXPORT void 
00666   getcardbounds(bdd& c, int& curmin, int& curmax);
00667   // END EXTRACT CARDINALITY
00668 
00669   GECODE_CPLTSET_EXPORT bdd 
00670   lexlt(unsigned int& xoff, unsigned int& yoff, 
00671         unsigned int& range, int n);
00672 
00673   GECODE_CPLTSET_EXPORT bdd 
00674   lexlq(unsigned int& xoff, unsigned int& yoff, 
00675         unsigned int& range, int n);
00676 
00677   GECODE_CPLTSET_EXPORT bdd 
00678   lexltrev(unsigned int& xoff, unsigned int& yoff, 
00679            unsigned int& range, int n);
00680 
00681   GECODE_CPLTSET_EXPORT bdd 
00682   lexlqrev(unsigned int& xoff, unsigned int& yoff, 
00683            unsigned int& range, int n);
00684 
00685   template <class View>
00686   void quantify(bdd& p, View& x) {
00687     bdd dom = x.dom();
00688     int s = x.offset();
00689     int w = s + x.tableWidth() - 1;
00690     manager.existquant(p, dom, s, w);
00691     // \todo check the update line from naryrec.icc "dom = p" ()
00692   }
00693 
00694 }}
00695 
00696 // STATISTICS: cpltset-support