parentiter2.h

00001 #ifndef PARENTITER2_H
00002 #define PARENTITER2_H
00003 
00004 #include "parentiter.h"
00005 
00006 /* ParentIter2 generalizes ParentIter, but allows multiple types.
00007  * The purpose is to iterate over all groundings of a parfeature
00008  * that include a certain set of constants in the arguments.
00009  * The user specifies the type of each argument, the constants required
00010  * to appear (possibly none), and the list of valid constants in the
00011  * domain for each type.
00012  */
00013 class ParentIter2
00014 {
00015 public:
00016     /* Constructor
00017      *
00018      * Arguments:
00019      *   required -- for each type, a lists of constants that must appear
00020      *               as arguments
00021      *   filler -- for each type, a list of constants that could appear
00022      *   types  -- the type for each argument.  The length of this array
00023      *             is the number of constants that will appear in the
00024      *             final configuration
00025      */
00026     ParentIter2(const Array<Array<int> >& required, 
00027             const Array<Array<int>*>* filler, const Array<int>& types)
00028         : firstTime_(true), size_(types.size())
00029     {
00030         // Count number of arguments of each type
00031         for (int i = 0; i < types.size(); i++) {
00032             while (numPerType_.size() <= types[i]) {
00033                 argMap_.append(Array<int>() );
00034                 numPerType_.append(0);
00035             }
00036             numPerType_[types[i]]++;
00037             argMap_[types[i]].append(i);
00038         }
00039 
00040         // Create one iterator for each type
00041         for (int i = 0; i < numPerType_.size(); i++) {
00042             piters_.append(ParentIter(required[i], 
00043                         (*filler)[i], numPerType_[i]));
00044         }
00045     }
00046 
00047 
00048     bool hasNextGrounding()
00049     {
00050         // See if there are any more configurations
00051         bool hasNext = false;
00052         for (int i = 0; i < piters_.size(); i++) {
00053             if (piters_[i].hasNextGrounding()) {
00054                 hasNext = true;
00055                 break;
00056             }
00057         }
00058         return hasNext;
00059     }
00060 
00061 
00062     bool getNextGrounding(Array<int>& grounding) 
00063     {
00064         grounding.clear();
00065         grounding.growToSize(size_);
00066 
00067         if (firstTime_) {
00068 
00069             pgrounds_.clear();
00070             pgrounds_.growToSize(piters_.size());
00071 
00072             // Get the first grounding
00073             for (int i = 0; i < piters_.size(); i++) {
00074                 piters_[i].getNextGrounding(pgrounds_[i]);
00075             }
00076             firstTime_ = false;
00077         } else {
00078             // Advance to the next configuration
00079             for (int i = 0; i < piters_.size(); i++) {
00080                 if (numPerType_[i] == 0) {
00081                     continue;
00082                 }
00083                 if (piters_[i].hasNextGrounding()) {
00084                     // Increment this configuration, and we're done
00085                     piters_[i].getNextGrounding(pgrounds_[i]);
00086                     break;
00087                 } else {
00088                     // Go back to first configuration
00089                     piters_[i].reset();
00090                     piters_[i].getNextGrounding(pgrounds_[i]);
00091                 }
00092             }
00093         }
00094 
00095         // Copy to the passed-in array
00096         for (int i = 0; i < numPerType_.size(); i++) {
00097             for (int j = 0; j < numPerType_[i]; j++) {
00098                 grounding[argMap_[i][j]] = pgrounds_[i][j];
00099             }
00100         }
00101 
00102         return hasNextGrounding();
00103     }
00104 
00105 private:
00106     Array<ParentIter> piters_;
00107     Array<Array<int> > argMap_;
00108     Array<Array<int> > pgrounds_;
00109     Array<int> numPerType_;
00110     bool firstTime_;
00111     int size_;
00112 };
00113 
00114 #endif // ndef PARENTITER2_H

Generated on Sun Jun 7 11:55:20 2009 for Alchemy by  doxygen 1.5.1