indextranslator.h

00001 /*
00002  * All of the documentation and software included in the
00003  * Alchemy Software is copyrighted by Stanley Kok, Parag
00004  * Singla, Matthew Richardson, Pedro Domingos, Marc
00005  * Sumner and Hoifung Poon.
00006  * 
00007  * Copyright [2004-07] Stanley Kok, Parag Singla, Matthew
00008  * Richardson, Pedro Domingos, Marc Sumner and Hoifung
00009  * Poon. All rights reserved.
00010  * 
00011  * Contact: Pedro Domingos, University of Washington
00012  * (pedrod@cs.washington.edu).
00013  * 
00014  * Redistribution and use in source and binary forms, with
00015  * or without modification, are permitted provided that
00016  * the following conditions are met:
00017  * 
00018  * 1. Redistributions of source code must retain the above
00019  * copyright notice, this list of conditions and the
00020  * following disclaimer.
00021  * 
00022  * 2. Redistributions in binary form must reproduce the
00023  * above copyright notice, this list of conditions and the
00024  * following disclaimer in the documentation and/or other
00025  * materials provided with the distribution.
00026  * 
00027  * 3. All advertising materials mentioning features or use
00028  * of this software must display the following
00029  * acknowledgment: "This product includes software
00030  * developed by Stanley Kok, Parag Singla, Matthew
00031  * Richardson, Pedro Domingos, Marc Sumner and Hoifung
00032  * Poon in the Department of Computer Science and
00033  * Engineering at the University of Washington".
00034  * 
00035  * 4. Your publications acknowledge the use or
00036  * contribution made by the Software to your research
00037  * using the following citation(s): 
00038  * Stanley Kok, Parag Singla, Matthew Richardson and
00039  * Pedro Domingos (2005). "The Alchemy System for
00040  * Statistical Relational AI", Technical Report,
00041  * Department of Computer Science and Engineering,
00042  * University of Washington, Seattle, WA.
00043  * http://www.cs.washington.edu/ai/alchemy.
00044  * 
00045  * 5. Neither the name of the University of Washington nor
00046  * the names of its contributors may be used to endorse or
00047  * promote products derived from this software without
00048  * specific prior written permission.
00049  * 
00050  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF WASHINGTON
00051  * AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
00052  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00053  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00054  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY
00055  * OF WASHINGTON OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
00056  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00057  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00058  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00059  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00060  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00061  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00062  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
00063  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00064  * 
00065  */
00066 #ifndef INDEXTRANSLATOR_H_NOV_29_2005
00067 #define INDEXTRANSLATOR_H_NOV_29_2005
00068 
00069 
00070 #include "mln.h"
00071 
00072 //NOTE: "domain index" and "database index" are used interchangeably
00073 
00074 struct IdxDiv { int idx; double div; };
00075 
00076 
00077 class IndexTranslator
00078 {
00079  public:
00080   IndexTranslator(const Array<MLN*>* const & mlns, 
00081                   const Array<Domain*>* const & domains) 
00082     : mlns_(mlns), domains_(domains), cIdxToCFIdxsPerDomain_(NULL), 
00083       wtsPerDomain_(NULL), gradsPerDomain_(NULL),
00084       clauseOrdering_(NULL), existFormulaOrdering_(NULL) 
00085   { createClauseIdxToClauseFormulaIdxsMap(); }
00086 
00087 
00088   ~IndexTranslator() 
00089   {
00090     if (cIdxToCFIdxsPerDomain_) 
00091     {
00092       for (int i = 0; i < cIdxToCFIdxsPerDomain_->size(); i++)
00093         (*cIdxToCFIdxsPerDomain_)[i].deleteItemsAndClear();
00094       delete cIdxToCFIdxsPerDomain_;
00095     }
00096     if (wtsPerDomain_) delete wtsPerDomain_;
00097     if (gradsPerDomain_) delete gradsPerDomain_;
00098     if (clauseOrdering_) 
00099     { clauseOrdering_->deleteItemsAndClear(); delete clauseOrdering_; }
00100     if (existFormulaOrdering_) delete existFormulaOrdering_;
00101   }    
00102 
00103 
00104     //Returns true if there are multiple databases, and there are formulas
00105     //whose CNF contains a different number of clauses for each database;
00106     //otherwise returns false. 
00107     //ASSUMPTION: the MLNs were formed from parsing the same .mln file
00108   static bool needIndexTranslator(const Array<MLN*>& mlns,
00109                                   const Array<Domain*>& domains)
00110   {
00111     if (mlns.size() <= 1) return false;
00112 
00113     for (int i = 1; i < mlns.size(); i++)
00114       if (mlns[0]->getNumClauses() != mlns[i]->getNumClauses()) return true;
00115 
00116     //there are more than one MLN and all MLNs have the same number of clauses
00117     //now check whether all tie-able formulas have one clause in their CNF
00118 
00119     bool allTiedFormulasHaveOneClause = true;
00120     for (int i = 0; i < mlns.size(); i++)
00121     {
00122       const FormulaAndClausesArray* fnca = mlns[i]->getFormulaAndClausesArray();
00123       for (int j = 0; j < fnca->size(); j++)
00124       {
00125         if (formulaWtTiedToClauseWts((*fnca)[j]) && 
00126             (*fnca)[j]->indexClauses->size() > 1)
00127         { 
00128           allTiedFormulasHaveOneClause = false;
00129           break;
00130         }
00131       }
00132       if (!allTiedFormulasHaveOneClause) break;
00133     }
00134 
00135     if (allTiedFormulasHaveOneClause) return false;
00136 
00137     //all MLNs have the same number of clauses, and a tie-able formula
00138     //has more than one clause
00139     
00140     //now check that the tie-able clauses are exactly the same across databases
00141 
00142     for (int i = 0; i < mlns[0]->getNumClauses(); i++)
00143     {
00144         //if this is a clause whose wt can be tied to the formula wt
00145       if (tieClauseWtToFormulaWt(mlns[0], i))
00146       {
00147         ostringstream oss0;
00148         mlns[0]->getClause(i)->printWithoutWtWithStrVar(oss0, domains[0]);
00149         for (int j = 1; j < mlns.size(); j++)
00150         {
00151           ostringstream ossj;
00152           mlns[j]->getClause(i)->printWithoutWtWithStrVar(ossj, domains[j]);
00153           if (oss0.str().compare(ossj.str()) != 0) return true;          
00154         }
00155       }
00156     }
00157     
00158     return false;
00159   }
00160 
00161 
00162   const Array<Array<Array<IdxDiv>*> >* 
00163   getClauseIdxToClauseFormulaIdxsPerDomain() const 
00164   { return cIdxToCFIdxsPerDomain_; }
00165 
00166   Array<Array<double> >* getWtsPerDomain() const { return wtsPerDomain_; }
00167 
00168   Array<Array<double> >* getGradsPerDomain() const { return gradsPerDomain_; }
00169 
00170   const ClauseHashArray* getClauseOrdering() const { return clauseOrdering_; }
00171 
00172   const StringHashArray* getExistFormulaOrdering() const 
00173   { return existFormulaOrdering_; }
00174 
00175   int getNumClausesAndExistFormulas() const 
00176   { return clauseOrdering_->size() + existFormulaOrdering_->size(); }
00177 
00178   
00179     //check that the sizes of cIdxToCFIdxsPerDomain_[d], wtsPerDomain_[d], and
00180     //gradsPerDomain_[d] is equal to the num of clauses in mln_[d] + numAdded
00181   bool checkCIdxWtsGradsSize(const int& numAdded)
00182   {
00183     for (int i = 0; i < mlns_->size(); i++) // for each domain
00184     {
00185       int sz = (*mlns_)[i]->getNumClauses() + numAdded;
00186       if ((*cIdxToCFIdxsPerDomain_)[i].size() != sz) return false;
00187       if ((*wtsPerDomain_)[i].size() != sz) return false;
00188       if ((*gradsPerDomain_)[i].size() != sz) return false;
00189     }
00190     return true;
00191   }
00192 
00193 
00194     //Size of wts must be sum of the sizes of clauseOrdering_, 
00195     //existFormulaOrdering_, appendedClauses, and appendedFormulas.
00196   void updateClauseFormulaWtsInMLNs(const Array<double>& wts,
00197                                     const Array<Clause*>*const& appendedClauses,
00198                                     const Array<string>*const& appendedFormulas)
00199   {
00200     assert(appendedClauses == NULL || appendedFormulas == NULL);
00201     Domain* dom0 = (*domains_)[0];
00202     for (int i = 0; i < mlns_->size(); i++) // for each domain
00203     {
00204       MLN* mln = (*mlns_)[i];
00205       Domain* dom = (*domains_)[i];
00206 
00207       for (int j = 0; j < clauseOrdering_->size(); j++)
00208       {
00209         Clause* c = (*clauseOrdering_)[j];
00210         if (i > 0 && c->containsConstants()) c->translateConstants(dom0, dom);
00211         Clause* cc = (Clause*) mln->findClause(c);
00212         if (i > 0 && c->containsConstants()) c->translateConstants(dom, dom0);
00213         cc->setWt(wts[j]);
00214       }
00215 
00216       int offset = clauseOrdering_->size();
00217 
00218       for (int j = 0; j < existFormulaOrdering_->size(); j++)
00219         mln->setFormulaWt((*existFormulaOrdering_)[j], wts[offset+j]);
00220 
00221       offset += existFormulaOrdering_->size();
00222 
00223       if (appendedClauses)
00224       {
00225         for (int j = 0; j < appendedClauses->size(); j++)
00226         {
00227           Clause* c = (*appendedClauses)[j];
00228           if (i > 0 && c->containsConstants()) c->translateConstants(dom0, dom);
00229           Clause* cc = (Clause*) mln->findClause(c);
00230           if (i > 0 && c->containsConstants()) c->translateConstants(dom, dom0);
00231           cc->setWt(wts[offset+j]);
00232         }
00233       }
00234       else
00235       if (appendedFormulas)
00236       {
00237         for (int j = 0; j < appendedFormulas->size(); j++)
00238           mln->setFormulaWt((*appendedFormulas)[j], wts[offset+j]);
00239       }       
00240     }
00241   }
00242 
00243 
00244   void getClauseFormulaWts(Array<double>& wts) const
00245   {
00246     wts.clear();
00247     wts.growToSize(clauseOrdering_->size() + existFormulaOrdering_->size());
00248     int a = 0;
00249     for (int j = 0; j < clauseOrdering_->size(); j++)
00250       wts[a++] = (*mlns_)[0]->findClause((*clauseOrdering_)[j])->getWt();
00251 
00252     for (int j = 0; j < existFormulaOrdering_->size(); j++)
00253       wts[a++] = (*mlns_)[0]->getFormulaWt((*existFormulaOrdering_)[j]);    
00254   }
00255 
00256 
00257     //There must be more than one MLN in mlns. The size of mlns_ must be the 
00258     //same as the size of domains_.
00259   void createClauseIdxToClauseFormulaIdxsMap()
00260   {
00261     assert(mlns_->size() == domains_->size());
00262     if (mlns_->size() <= 1) return;
00263     if (cIdxToCFIdxsPerDomain_) 
00264     {
00265       for (int i = 0; i < cIdxToCFIdxsPerDomain_->size(); i++)
00266         (*cIdxToCFIdxsPerDomain_)[i].deleteItemsAndClear();
00267       delete cIdxToCFIdxsPerDomain_;
00268     }
00269     if (wtsPerDomain_) delete wtsPerDomain_;
00270     if (gradsPerDomain_) delete gradsPerDomain_;
00271     if (clauseOrdering_)     
00272     { clauseOrdering_->deleteItemsAndClear(); delete clauseOrdering_; }
00273     if (existFormulaOrdering_) delete existFormulaOrdering_;
00274 
00275     trackClauseConstants();
00276     clauseOrdering_ = new ClauseHashArray;
00277     existFormulaOrdering_ = new StringHashArray;
00278     createClausesFormulasOrdering((*mlns_)[0], clauseOrdering_, 
00279                                   existFormulaOrdering_);
00280 
00281     cIdxToCFIdxsPerDomain_ = new Array<Array<Array<IdxDiv>*> >;
00282     wtsPerDomain_ = new Array<Array<double> >;
00283     gradsPerDomain_ = new Array<Array<double> >;
00284     cIdxToCFIdxsPerDomain_->growToSize(mlns_->size());
00285     wtsPerDomain_->growToSize(mlns_->size());
00286     gradsPerDomain_->growToSize(mlns_->size());
00287 
00288     Domain* dom0 = (*domains_)[0];
00289     for (int i = 0; i < mlns_->size(); i++) // for each domain
00290     {
00291       MLN* mln = (*mlns_)[i];
00292       Domain* dom = (*domains_)[i];
00293       const FormulaAndClausesArray* fnca = mln->getFormulaAndClausesArray();
00294       Array<Array<IdxDiv>*>& cIdxToCFIdxsMap = (*cIdxToCFIdxsPerDomain_)[i];
00295       cIdxToCFIdxsMap.growToSize(mln->getNumClauses());
00296       (*wtsPerDomain_)[i].growToSize(mln->getNumClauses());
00297       (*gradsPerDomain_)[i].growToSize(mln->getNumClauses());
00298 
00299       for (int j = 0; j < mln->getNumClauses(); j++) // for each clause in MLN
00300       {
00301         Array<IdxDiv>* cfIdxs = new Array<IdxDiv>;
00302         cIdxToCFIdxsMap[j] = cfIdxs;
00303 
00304           //if we don't need to tie the clause weight to formula weight as when
00305           //this clause is in the CNF of a non-existentially quant. and
00306           //non-existentially and uniquely quant. formula.
00307         if (noTieClauseWtToFormulaWt(mln,j))
00308         {
00309           Clause* c = (Clause*) mln->getClause(j);
00310           if (i > 0 && c->containsConstants()) c->translateConstants(dom, dom0);
00311           int idx = clauseOrdering_->find(c);
00312           cfIdxs->append(IdxDiv());
00313           cfIdxs->lastItem().idx = idx;
00314           cfIdxs->lastItem().div = 1;
00315           if (i > 0 && c->containsConstants()) c->translateConstants(dom0, dom);
00316           if (idx < 0) 
00317           { 
00318             cout <<"ERROR: in IndexTranslator::"
00319                  << "createClauseIdxToClauseFormulaIdxsMap(): clause ";
00320             c->printWithoutWtWithStrVar(cout, dom); cout << "not found!"<<endl;
00321             exit(-1);
00322           }
00323         }
00324 
00325           //if we must tie the clause weight to formula weight as when
00326           //the clause is in the CNF of an existentially quantified formula,
00327           //or an existentially and uniquely quantified formula,
00328         if (tieClauseWtToFormulaWt(mln, j))
00329         {
00330           const Array<FormulaClauseIndexes*>& fciArr 
00331             = mln->getMLNClauseInfo(j)->formulaClauseIndexes;
00332 
00333           for (int k = 0; k < fciArr.size(); k++)
00334           {
00335             int fidx = *(fciArr[k]->formulaIndex);
00336             if (!formulaWtTiedToClauseWts((*fnca)[fidx])) continue;
00337             string formula = (*fnca)[fidx]->formula;
00338             int numClauses = (*fnca)[fidx]->indexClauses->size();
00339             int idx = existFormulaOrdering_->find(formula);
00340             cfIdxs->append(IdxDiv());
00341                 //exist. quant. formulas comes after 'normal' clauses
00342             cfIdxs->lastItem().idx = idx + clauseOrdering_->size();
00343 
00344             if (mln->isExistClause(j))
00345               cfIdxs->lastItem().div = numClauses;
00346             else
00347             if (mln->isExistUniqueClause(j))
00348             {
00349                 //this clause states that there is at least one true value
00350               Clause* firstClause 
00351                 = (*((*fnca)[fidx]->indexClauses))[0]->clause;
00352               int numPreds = firstClause->getNumPredicates();
00353               Clause* c = (Clause*) mln->getClause(j);
00354               if (c->same(firstClause))
00355                 cfIdxs->lastItem().div = (numPreds > 1) ? numPreds+1 : 1;
00356               else
00357                 cfIdxs->lastItem().div = (numPreds*numPreds-1)*0.5;
00358             }
00359             else
00360               assert(false);
00361 
00362 
00363             if (idx < 0)
00364             { 
00365               cout << "ERROR: in createClauseIdxToClauseFormulaIdxsMap(): "
00366                    << "formula " << formula << "not found!" << endl;
00367               exit(-1);
00368             }
00369           }
00370         }
00371 
00372         cfIdxs->compress();
00373 
00374       } // for each clause in MLN
00375     } // for each DB
00376   }
00377 
00378 
00379   void appendClauseIdxToClauseFormulaIdxs(const int& numCFIdxs,
00380                                           const int& numCIdxsPerCFIdx,
00381                                           const int& domainIdx)
00382   {
00383     if (numCFIdxs == 0) return;
00384     Array<Array<IdxDiv>*>& cidxs = (*cIdxToCFIdxsPerDomain_)[domainIdx];
00385     Array<double>& wts = (*wtsPerDomain_)[domainIdx];
00386     Array<double>& grads = (*gradsPerDomain_)[domainIdx];
00387     int numClausesFormulas = getNumClausesAndExistFormulas();
00388     
00389     for (int j = 0; j < numCFIdxs; j++)
00390     {
00391       int cfidx = numClausesFormulas + j;
00392       for (int k = 0; k < numCIdxsPerCFIdx; k++)
00393       {
00394         IdxDiv idiv;
00395         idiv.idx = cfidx;
00396         idiv.div = 1;
00397         Array<IdxDiv>* arr = new Array<IdxDiv>(1);
00398         arr->append(idiv);
00399         cidxs.append(arr);
00400         
00401         wts.append(0.0);
00402         grads.append(0.0);          
00403       }
00404     }
00405   }
00406 
00407   
00408   void appendClauseIdxToClauseFormulaIdxs(const int& numCFIdxs,
00409                                           const int& numCIdxsPerCFIdx)
00410   {
00411     if (numCFIdxs == 0) return;
00412     for (int i = 0; i < cIdxToCFIdxsPerDomain_->size(); i++)
00413       appendClauseIdxToClauseFormulaIdxs(numCFIdxs, numCIdxsPerCFIdx, i);
00414   }
00415 
00416 
00417   void removeClauseIdxToClauseFormulaIdxs(const int& numCFIdxs,
00418                                           const int& numCIdxsPerCFIdx,
00419                                           const int& domainIdx)
00420   {
00421     if (numCFIdxs == 0) return;
00422     Array<Array<IdxDiv>*>& cidxs = (*cIdxToCFIdxsPerDomain_)[domainIdx];
00423     Array<double>& wts = (*wtsPerDomain_)[domainIdx];
00424     Array<double>& grads = (*gradsPerDomain_)[domainIdx];
00425     
00426     for (int j = 0; j < numCFIdxs; j++)
00427       for (int k = 0; k < numCIdxsPerCFIdx; k++)
00428       {
00429         delete cidxs.removeLastItem();
00430         wts.removeLastItem();
00431         grads.removeLastItem();          
00432       }    
00433   }
00434 
00435 
00436   void removeClauseIdxToClauseFormulaIdxs(const int& numCFIdxs,
00437                                           const int& numCIdxsPerCFIdx)
00438   {
00439     if (numCFIdxs == 0) return;
00440     for (int i = 0; i < cIdxToCFIdxsPerDomain_->size(); i++)
00441       removeClauseIdxToClauseFormulaIdxs(numCFIdxs, numCIdxsPerCFIdx, i);
00442   }
00443 
00444 
00445   void setPriorMeans(Array<double>& priorMeans)
00446   {
00447     priorMeans.clear();
00448     priorMeans.growToSize(clauseOrdering_->size() + 
00449                           existFormulaOrdering_->size());
00450     int m = 0;
00451     MLN* mln0 = (*mlns_)[0];
00452 
00453     for (int i = 0; i < clauseOrdering_->size(); i++)
00454     {
00455       Clause* c = (*clauseOrdering_)[i]; 
00456       int cidx = mln0->findClauseIdx(c);      
00457       priorMeans[m++] = mln0->getMLNClauseInfo(cidx)->priorMean;
00458     }
00459     
00460     const FormulaAndClausesArray* fnca = mln0->getFormulaAndClausesArray();
00461     for (int i = 0; i < existFormulaOrdering_->size(); i++)
00462     {
00463       FormulaAndClauses tmp((*existFormulaOrdering_)[i], 0, false);
00464       int a = fnca->find(&tmp);
00465       assert(a >= 0);
00466       priorMeans[m++] = (*fnca)[a]->priorMean;
00467     }
00468   }
00469 
00470 
00471     //Maps each clause index in the array to the clause/formula index, and
00472     //replaces the former with the latter.
00473   void getClauseFormulaIndexes(Array<int>& clauseIndexes, const int& domainIdx)
00474   {
00475     for (int i = 0; i < clauseIndexes.size(); i++)
00476     {
00477       int cidx = clauseIndexes[i];
00478       Array<IdxDiv>* idxDivs = (*cIdxToCFIdxsPerDomain_)[domainIdx][cidx];
00479       for (int j = 0; j < idxDivs->size(); j++)
00480         if ((*idxDivs)[j].idx < clauseOrdering_->size())
00481         {
00482             //only get the index of clauses (and not those of exist.
00483             //quant. formulas)
00484           assert((*idxDivs)[j].div == 1);
00485           clauseIndexes[i] = (*idxDivs)[j].idx;
00486         }
00487     }
00488   }
00489 
00490 
00491     //assign the weights belonging to clauses (and none of those belonging to
00492     //existentially/exitentially and uniquely  quantified formulas) to the MLNs
00493   void assignNonTiedClauseWtsToMLNs(const double* const & wts)
00494   {
00495     for (int i = 0; i < mlns_->size(); i++)
00496     {
00497       MLN* mln = (*mlns_)[i];
00498       for (int j = 0; j < mln->getNumClauses(); j++)
00499       {
00500         if (!noTieClauseWtToFormulaWt(mln,j)) continue;
00501 
00502         Clause* c = ((Clause*) mln->getClause(j));
00503         assert(inClauseOrdering(c, i));
00504         Array<IdxDiv>* idxDivs =(*cIdxToCFIdxsPerDomain_)[i][j];
00505         double wt = 0;
00506         for (int k = 0; k < idxDivs->size(); k++)
00507         {
00508             //don't assign the weights of existential formulas to clauses
00509           if ((*idxDivs)[k].idx < clauseOrdering_->size())
00510             wt += wts[ (*idxDivs)[k].idx ] / (*idxDivs)[k].div;
00511         }
00512         c->setWt(wt);
00513       }
00514     }
00515   }
00516 
00517   
00518   void printClauseFormulaWts(ostream& out, const bool& includeIdx)
00519   {
00520     Array<double> wts;
00521     getClauseFormulaWts(wts);
00522       //print those clauses that appear in a non-exist. quant. formula
00523     Array<Clause*> tmp;
00524     for (int i = 0; i < clauseOrdering_->size(); i++) 
00525     {
00526       (*clauseOrdering_)[i]->setWt(wts[i]);
00527       tmp.append((*clauseOrdering_)[i]);
00528     }
00529     Clause::sortByLen(tmp);
00530       
00531     out.setf(ios_base::left, ios_base::adjustfield);
00532     for (int i = 0; i < tmp.size(); i++)
00533     {
00534       if (includeIdx) { out << i << ":  "; out.width(14); }
00535       else            { out.width(10); }
00536       out << tmp[i]->getWt(); out.width(0); out << " ";
00537       tmp[i]->printWithoutWtWithStrVar(out, (*domains_)[0]); out << endl; 
00538     }
00539     out.width(0);
00540 
00541     for (int i = 0; i < existFormulaOrdering_->size(); i++)
00542     {
00543       int idx = i+clauseOrdering_->size();
00544       if (includeIdx) { out << idx <<":  ";out.width(14);}
00545       else            { out.width(10); }
00546       out << wts[idx]; out.width(0); 
00547       out << " " << (*existFormulaOrdering_)[i] << endl;      
00548     }
00549     out.width(0);
00550   }
00551 
00552 
00553     //used by VotedPerceptron
00554   void setRelevantClausesFormulas(Array<bool>& relevantClausesFormulas,
00555                                   const Array<bool>& relevantClausesInMLN0)
00556   {
00557     const Array<bool>& relevantClauses = relevantClausesInMLN0;
00558 
00559     if (relevantClausesFormulas.size() < relevantClauses.size())
00560       relevantClausesFormulas.growToSize(relevantClauses.size());
00561     else
00562     if (relevantClausesFormulas.size() > relevantClauses.size())
00563       relevantClausesFormulas.shrinkToSize(relevantClauses.size());
00564       
00565     for (int i = 0; i < relevantClausesFormulas.size(); i++)
00566       relevantClausesFormulas[i] = false;
00567 
00568      
00569     for (int i = 0; i < clauseOrdering_->size(); i++)
00570     {
00571       int cidx = (*mlns_)[0]->findClauseIdx((*clauseOrdering_)[i]);
00572       relevantClausesFormulas[i] = relevantClauses[cidx];
00573     }
00574 
00575     int offset = clauseOrdering_->size();      
00576       
00577     for (int i = 0; i < existFormulaOrdering_->size(); i++)
00578     {
00579       const IndexClauseHashArray* icha 
00580         = (*mlns_)[0]->getClausesOfFormula((*existFormulaOrdering_)[i]);
00581       for (int j = 0; j < icha->size(); j++)
00582       {
00583         int cidx = (*mlns_)[0]->findClauseIdx((*icha)[j]->clause);
00584         relevantClausesFormulas[offset+i] = relevantClauses[cidx];
00585         if (relevantClausesFormulas[offset+i]) break;
00586       }
00587     }
00588   }
00589 
00590 
00591   void printRelevantClausesFormulas(ostream& out,
00592                                     const Array<bool>& relevantClausesFormulas)
00593   {
00594     for (int i = 0; i < clauseOrdering_->size(); i++)
00595     {
00596       if (relevantClausesFormulas[i])
00597       {
00598         out << i << ": ";
00599         (*clauseOrdering_)[i]->printWithoutWtWithStrVar(out, (*domains_)[0]);
00600         out << endl;
00601       }
00602     }
00603     
00604     int offset = clauseOrdering_->size();
00605 
00606     for (int i = 0; i < existFormulaOrdering_->size(); i++)
00607     {
00608       if (relevantClausesFormulas[offset+i])
00609         out << offset+i << ": " << (*existFormulaOrdering_)[i] << endl;
00610     }
00611   }
00612 
00613 
00614  private:
00615   void trackClauseConstants()
00616   {
00617     for (int i = 0; i < mlns_->size(); i++)
00618       for (int j = 0; j < (*mlns_)[i]->getNumClauses(); j++)
00619         if (noTieClauseWtToFormulaWt((*mlns_)[i], j))
00620         {
00621           Clause* c = (Clause*) (*mlns_)[i]->getClause(j);
00622           if (c->getAuxClauseData() == NULL) c->newAuxClauseData();
00623           c->trackConstants();
00624         }
00625   }
00626 
00627 
00628   void createClausesFormulasOrdering(MLN* const & mln, 
00629                                      ClauseHashArray* const & clauses,
00630                                      StringHashArray* const & existFormulas)
00631   {
00632     for (int i = 0; i < mln->getNumClauses(); i++)
00633       if (noTieClauseWtToFormulaWt(mln,i))
00634       { 
00635         Clause* c = new Clause( *((Clause*)mln->getClause(i)) );
00636         clauses->append(c);
00637       }
00638 
00639     const FormulaAndClausesArray* fnca = mln->getFormulaAndClausesArray();
00640     for (int i = 0; i < fnca->size(); i++)
00641       if (formulaWtTiedToClauseWts((*fnca)[i])) 
00642         existFormulas->append((*fnca)[i]->formula);
00643   }
00644 
00645 
00646   bool inClauseOrdering(Clause* const & c, const int& domainIdx)
00647   {
00648     assert(c->getAuxClauseData());
00649     if (domainIdx > 0 && c->containsConstants()) 
00650       c->translateConstants((*domains_)[domainIdx], (*domains_)[0]);
00651     bool in = (clauseOrdering_->find(c) >= 0);
00652     if (domainIdx > 0 && c->containsConstants()) 
00653       c->translateConstants((*domains_)[0], (*domains_)[domainIdx]);
00654     return in;
00655   }
00656   
00657 
00658     //Returns true if the clause weights must be tied to the formulas (as when
00659     //the clause belongs to the CNF of an existentially quantified or 
00660     //existentially and uniquely quantified formula
00661     //i is the clause's index in mln
00662   static bool tieClauseWtToFormulaWt(const MLN* const & mln, const int& i)
00663   { return (mln->isExistClause(i) || mln->isExistUniqueClause(i)); }
00664 
00665 
00666   static bool formulaWtTiedToClauseWts(const FormulaAndClauses* const & fnc)
00667   { return (fnc->hasExist || fnc->isExistUnique); }
00668 
00669 
00670     //Returns true if the clause weights need not be tied to the formulas 
00671     //(as when the clause belongs to the CNF of a non-existentially quantified 
00672     //and non-existentially and uniquely quantified formula
00673     //i is the clause's index in mln
00674   bool noTieClauseWtToFormulaWt(const MLN* const & mln, const int& i)
00675   { return mln->clauseInNonExistAndNonExistUniqueFormulaCNF(i); }
00676 
00677  private:
00678   const Array<MLN*>* mlns_; // not owned by this object; do not delete;
00679   const Array<Domain*>* domains_; // not owned by this object; do not delete;
00680 
00681     //cIdxToCFIdxsPerDomain_[d] maps clause indexes (cIdx) in an MLN to 
00682     //clause/formula indexes (CFIdxs) for domain d.
00683     //Used when the clauses across multiple domains do not line up perfectly
00684     //as when an existential formula has a different number of CNF clauses for
00685     //different domains. Used in PseudoLogLikelihood.
00686   Array<Array<Array<IdxDiv>*> >* cIdxToCFIdxsPerDomain_;
00687   Array<Array<double> >* wtsPerDomain_; //Used in PseudoLogLikelihood
00688   Array<Array<double> >* gradsPerDomain_; //Used in PseudoLogLikelihood
00689 
00690   ClauseHashArray* clauseOrdering_; 
00691   StringHashArray* existFormulaOrdering_;
00692 };
00693 
00694 
00695 #endif

Generated on Tue Jan 16 05:30:03 2007 for Alchemy by  doxygen 1.5.1