LProposalTable::LProposalTable(int parentsSize,int maxTruthValue_):totalSamplesCollected(0),maxTruthValue(maxTruthValue_) { distribution.clear(); adaptiveMLECounter.clear(); totalSamplesCollected.clear(); normConstants.clear(); distribution.resize(parentsSize); adaptiveMLECounter.resize(parentsSize); totalSamplesCollected.resize(parentsSize); normConstants.resize(parentsSize); for(unsigned int i=0;i<distribution.size();i++) { distribution[i].resize(maxTruthValue+1); adaptiveMLECounter[i].resize(maxTruthValue+1); for(unsigned int j=0;j<distribution[i].size();j++) distribution[i].at(j) = LogDouble(1.0,false)/LogDouble(maxTruthValue+1,false); //set the norm constant based on domain size normConstants[i] = distribution[i].at(0) + distribution[i].at(distribution[i].size()-1); LogDouble factor; for(unsigned int j=1;j<distribution[i].size()-1;j++) factor = factor + distribution[i].at(j); if(!factor.is_zero) factor = factor*LogDouble(maxTruthValue,false); else factor = LogDouble(maxTruthValue,false); normConstants[i] = normConstants[i] + factor; } }
/* //Functions to support Rao-Blackwell estimation void LvrQueryUpdater::updateQueryValuesLVGibbsRB(Atom* atom,LogDouble prob,int sampledvalue) { if(!isNormIdInQuery(atom->symbol->normParentId)) return; //ground the atom, if not grounded if(atom->isConstant()) { vector<int> intRep(atom->terms.size()+1); intRep[0] = atom->symbol->normParentId; for(unsigned int i=0;i<atom->terms.size();i++) intRep[i+1] = atom->terms[i]->domain[0]; bool value; bool found = lvrAtomHashUpdateFlags->getValue(intRep,value); if(!found) return; if(!value) { rbestimates->incrementValue(atom,&prob); //currentSampledValue->update(atom,sampledvalue); lvrAtomHashUpdateFlags->update(atom,true); } } else { vector<vector<int> > permutedList; LvrPermutations::permuteTerms(atom->terms,permutedList); set<int> indexes; while(indexes.size()!=sampledvalue) { int ind = LvRandomGenUtil::Instance()->getRandomPosition(permutedList.size()); indexes.insert(ind); } for(unsigned int i=0;i<permutedList.size();i++) { vector<int> intRep(permutedList[i].size()+1); intRep[0] = atom->symbol->normParentId; for(unsigned int jj=0;jj<permutedList[i].size();jj++) intRep[jj+1] = permutedList[i].at(jj); bool value; bool found = lvrAtomHashUpdateFlags->getValue(intRep,value); if(!found) continue; if(!value) { //bool assignment = false; int assignment = 0; if(indexes.find(i)!=indexes.end()) { rbestimates->incrementValue(atom,&prob); //assignment = true; assignment = 1; } else { LogDouble neg = LogDouble(1.0-exp(prob.value),false); rbestimates->incrementValue(atom,&neg); } ///currentSampledValue->update(intRep,assignment); //currentSampledValue->update(intRep,assignment); lvrAtomHashUpdateFlags->update(intRep,true); } } } } */ void LvrQueryUpdater::updateQueryValuesLVGibbsRB(Atom* atom,vector<LogDouble> probs) { if(!isNormIdInQuery(atom->symbol->normParentId)) return; if(probs.size()!=atom->getNumberOfGroundings()+1) { cout<<"Error!!"<<endl; return; } //ground the atom, if not grounded if(atom->isConstant()) { vector<int> intRep(atom->terms.size()+1); intRep[0] = atom->symbol->normParentId; for(unsigned int i=0;i<atom->terms.size();i++) intRep[i+1] = atom->terms[i]->domain[0]; bool value; bool found = lvrAtomHashUpdateFlags->getValue(intRep,value); if(!found) return; if(!value) { rbestimates->incrementValue(atom,&probs[1]); //currentSampledValue->update(atom,sampledvalue); lvrAtomHashUpdateFlags->update(atom,true); } //cout<<probs[0]<<" "<<probs[1]<<endl; } else { //compute the grounded probability using the lifted probs LogDouble prob; for(unsigned int i=1;i<probs.size();i++) { //prob = prob + probs[i]/LMathUtils::Instance()->getCoeff(atom->getNumberOfGroundings(),i); LogDouble coef = LogDouble(i,false)/LogDouble(atom->getNumberOfGroundings(),false); //LogDouble coef(1,false); prob = prob + probs[i]*coef; } //cout<<prob<<endl; vector<vector<int> > permutedList; LvrPermutations::permuteTerms(atom->terms,permutedList); for(unsigned int i=0;i<permutedList.size();i++) { vector<int> intRep(permutedList[i].size()+1); intRep[0] = atom->symbol->normParentId; for(unsigned int jj=0;jj<permutedList[i].size();jj++) intRep[jj+1] = permutedList[i].at(jj); bool value; bool found = lvrAtomHashUpdateFlags->getValue(intRep,value); if(!found) continue; if(!value) { rbestimates->incrementValue(intRep,&prob); lvrAtomHashUpdateFlags->update(intRep,true); } } } }
LogDouble LPTPSearch::CNFWeight(vector<WClause*>& CNF,set<int>* dontCareQueries) { //compute the total size of the domains of atoms in CNF set<int> completedAtomIds; map<int,LogDouble> weights; map<int,int> numGroundings; for(int i=0;i<mln.symbols.size();i++) { numGroundings[mln.symbols[i]->parentId]=0; weights[mln.symbols[i]->parentId] = mln.symbols[i]->pweight+mln.symbols[i]->nweight; } for(int i=0;i<CNF.size();i++) { for(int j=0;j<CNF[i]->atoms.size();j++) { if(completedAtomIds.count(CNF[i]->atoms[j]->symbol->id) == 0) { completedAtomIds.insert(CNF[i]->atoms[j]->symbol->id); if(dontCareQueries) { //check the query table and add hashes of groundings present in the query table lvrptpSearchTree->getHashValues(CNF[i]->atoms[j],(*dontCareQueries)); } } else { //identical atom has already been considered do not recount atom continue; } int totalSize=1; for(int k=0;k<CNF[i]->atoms[j]->terms.size();k++) { totalSize *= CNF[i]->atoms[j]->terms[k]->domain.size(); } map<int,int>::iterator it = numGroundings.find(CNF[i]->atoms[j]->symbol->parentId); if(it!=numGroundings.end()) { it->second += totalSize; } } } LogDouble totalWeight=LogDouble(1,false); for(map<int,int>::iterator it = numGroundings.begin();it!=numGroundings.end();it++) { if(it->second != 0) { map<int,LogDouble>::iterator it1 = weights.find(it->first); LogDouble atomWt=LogDouble(1,false); LogDouble::LDPower(it1->second,it->second,atomWt); totalWeight *= atomWt; } } if(totalWeight.is_zero) return LogDouble(1,false); else return totalWeight; }
PredicateSymbol* LiftedAlgsConvertor::createPredicateSymbol(Predicate* pred) { int predicateId = pred->getId(); vector<int> var_types(pred->getNumTerms()); string symbolName(pred->getName()); PredicateSymbol* pSymbol = new PredicateSymbol(predicateId,symbolName,var_types,LogDouble(1,false),LogDouble(1,false),predicateId); return pSymbol; }
void LiftedAlgsConvertor::updateMLNWeights(vector<double> weights) { for(unsigned int i=0;i<lvrMln->clauses.size();i++) { //get the new weight based on the original clause index lvrMln->clauses[i]->weight = LogDouble(weights[lvrMln->clauses[i]->originalClauseIndex],false); } }
LogDouble LogDouble::operator*(const LogDouble& other) const { if (is_zero || other.is_zero) { return LogDouble(); } LogDouble out(other); out.value += value; return out; }
void LvrQueryUpdater::normalizeRB(int iterations) { vector<LogDouble*> rbest = rbestimates->getAllData(); for(unsigned int i=0;i<rbest.size();i++) { LogDouble tmp = *(rbest[i])/LogDouble(iterations,false); currentProbabilities[i] = exp(tmp.value); } }
LogDouble LogDouble::operator/(const LogDouble& other) const { if (is_zero || other.is_zero) { return LogDouble(); } LogDouble out(value); out.value -= other.value; return out; }
void LProposalTable::updateDistribution(double learningRate) { for(unsigned int i=0;i<distribution.size();i++) { if(totalSamplesCollected[i] == 0) continue; double norm = 0; vector<double> newProbabilities(distribution[i].size()); for(unsigned int j=0;j<distribution[i].size();j++) { newProbabilities[j] = (double)adaptiveMLECounter[i].at(j)/(double)totalSamplesCollected[i]; //distribution[i].at(j) = (double)adaptiveMLECounter[i].at(j)/(double)totalSamplesCollected[i]; //norm += distribution[i].at(j); norm += newProbabilities[j]; //reset the mle counter for the next updation adaptiveMLECounter[i].at(j) = 0; } //Use adaptive IS using the gradient descent rule LogDouble newNorm; for(unsigned int j=0;j<distribution[i].size();j++) { distribution[i].at(j) = distribution[i].at(j) + LogDouble((newProbabilities[j]-exp(distribution[i].at(j).value))*learningRate,false); newNorm += distribution[i].at(j); } for(unsigned int j=0;j<distribution[i].size();j++) { distribution[i].at(j) = distribution[i].at(j)/newNorm; } //update the norm constants normConstants[i] = distribution[i].at(0) + distribution[i].at(distribution[i].size()-1); LogDouble factor; for(unsigned int j=1;j<distribution[i].size()-1;j++) factor = factor + distribution[i].at(j); if(!factor.is_zero) factor = factor*LogDouble(maxTruthValue,false); else factor = LogDouble(maxTruthValue,false); normConstants[i] = normConstants[i] + factor; //RESET the sample counter totalSamplesCollected[i] = 0; } }
//inject the training errors loop(int time, range(totalTime)) { fill(dEdYTerms, LogDouble(0)); View<LogDouble> fvars = forwardVariables[time]; View<LogDouble> bvars = backwardVariables[time]; loop (int s, range(totalSegments)) { //k = blank for even s, target label for odd s int k = (s&1) ? seq.labelSeq[s/2] : blank; dEdYTerms[k] += (fvars[s] * bvars[s]); }
LogDouble LogDouble::Factorial(int n) { if(n==0) return LogDouble(1.0,false); LogDouble fact(n,false); for(unsigned int i=n-1;i>1;i--) { LogDouble t (i,false); fact*=t; } return fact; }
LogDouble LPTPSearch::startApproxWeightedModelCounting(LvrParams* params) { //normalizer->normalizeClauses(mln.clauses,true,false); cout<<"Starting Lifted Weighted Model Counting..."<<endl; time_t start; time(&start); cout<<"Time ="<<ctime(&start)<<endl; LogDouble ZApprox; int iterations = 0; if(params->maxSteps <= 0) params->maxSteps = MAXSTEPSINFER; if(params->maxSeconds <= 0) params->maxSeconds = MAXSECONDSINFER; while(1) { //make a copy of normalized clauses vector<WClause*> clauses; LvrMLN::copyAllClauses(mln.clauses,clauses); LogDouble currZ = weightedModelCountApprox(clauses)*mln.conversionFactor; //update approximation ZApprox = ZApprox*LogDouble(iterations,false) + currZ; iterations++; //take average ZApprox = ZApprox / LogDouble(iterations,false); //cout<<"iteration="<<iterations<<", currZ="<<currZ<<"currZ (Log Space)="<<currZ.value<<", ZApprox="<<ZApprox<<", ZApprox(Log Space)="<<ZApprox.value<<endl; cout<<"iteration="<<iterations<<", currZ : "; currZ.printValue(); cout<<", ZApprox : "; ZApprox.printValue(); cout<<endl; if(iterations >= params->maxSteps) return ZApprox; time_t currTime; time(&currTime); if(difftime(currTime,start) > params->maxSeconds) break; } return 0; }
void LvrQueryUpdater::updateGibbsDontCareRB() { vector<bool> values; vector<int> keys; lvrAtomHashUpdateFlags->getAllKeyValuePairs(keys,values); for(unsigned int i=0;i<values.size();i++) { if(!values[i]) { rbestimates->incrementValue(keys[i],&(LogDouble(0.5,false))); } lvrAtomHashUpdateFlags->setValue(keys[i],false); } }
void LvrQueryUpdater::updateAllImportanceWeightsRB(LogDouble currentIterWeight) { vector<LogDouble*> values; vector<int> keys; cumulativeWeight->getAllKeyValuePairs(keys,values); for(unsigned int i=0;i<keys.size();i++) { //bool sampleValue; LogDouble* sampleValue; bool found = rbestimates->getValue(keys[i],sampleValue); if(!found) continue; (*values[i]) = (*values[i]) + (*sampleValue)*currentIterWeight; (*sampleValue) = LogDouble(0,false); } }
void LogDouble::LDPower(LogDouble in,int n,LogDouble& out) { if (n==0) { return; } if(in.is_zero) { out.is_zero = true; return; } out=LogDouble(in.value*n); //for(unsigned int i=0;i<n;i++) //out = out*in; }
void LvrQueryUpdater::updateAllImportanceWeights(LogDouble currentIterWeight) { vector<LogDouble*> values; vector<int> keys; cumulativeWeight->getAllKeyValuePairs(keys,values); for(unsigned int i=0;i<keys.size();i++) { //bool sampleValue; int sampleValue; bool found = currentSampledValue->getValue(keys[i],sampleValue); if(!found) continue; if(sampleValue == 0) continue; else if(sampleValue==1) (*values[i]) = (*values[i]) + currentIterWeight; else if(sampleValue == -1) (*values[i]) = (*values[i]) + currentIterWeight/LogDouble(2,false); } }
void LProposalTable::sampleDistribution(int index) { if(index < 0 || index > distribution.size()) { return; } vector<LogDouble> cdf(distribution[index].size()); cdf[0] = distribution[index].at(0); for(unsigned int i=1;i<distribution[index].size()-1;i++) { cdf[i] = cdf[i-1]+distribution[index].at(i); } cdf[cdf.size()-1] = LogDouble(1,false); double u = LvRandomGenUtil::Instance()->getNormRand(); LogDouble lu(u,false); int nTrues = lower_bound(cdf.begin(),cdf.end(),lu) - cdf.begin(); sampledValue = nTrues; sampledProbability = distribution[index].at(nTrues); //update the appropriate counter adaptiveMLECounter[index].at(nTrues)++; totalSamplesCollected[index]++; }
LogDouble LExtensions::unitPropagation(vector<WClause*>& CNF,bool ptpexactmar) { LogDouble val(1,false); while(1) { //maintain a set of current unit clause predicate id's vector<int> unitPredicateIds; vector<bool> unitPredicateIdSign; for(unsigned int i=0; i<CNF.size(); i++) { if(CNF[i]->atoms.size()==1 && !CNF[i]->satisfied) { if(ptpexactmar) { //do not unit propagate on query predicates if(LvrQueryUpdater::isInstanceCreated()) { if(LvrQueryUpdater::Instance()->isNormIdInQuery(CNF[i]->atoms[0]->symbol->normParentId)) continue; } } int matchingId = -1; for(unsigned int j=0; j<unitPredicateIds.size(); j++) { if(unitPredicateIds[j]==CNF[i]->atoms[0]->symbol->id) { matchingId=j; break; } } if(matchingId != -1) { //if signs are the same, delete one of them since equivalent if(CNF[i]->sign[0] == unitPredicateIdSign[matchingId]) { removeItem(CNF,i); i--; } else { //conflicting unit clauses can never be satisfied return LogDouble(0,false); } } else { //set unit clause to satisfied CNF[i]->satisfied = true; //compute weight val=val*getUnitClauseWeightWMPTP(CNF[i]); unitPredicateIds.push_back(CNF[i]->atoms[0]->symbol->id); unitPredicateIdSign.push_back(CNF[i]->sign[0]); //remove atom from unit clause and count its weight CNF[i]->removeAtom(0); i--; } } } bool isCNFChanged = false; for(unsigned int i=0; i<unitPredicateIds.size(); i++) { //delete all clauses with conflicting sign for the unit atom for(unsigned int j=0; j<CNF.size(); j++) { for(unsigned int k=0; k<CNF[j]->atoms.size(); k++) { if(CNF[j]->atoms[k]->symbol->id == unitPredicateIds[i]) { if(CNF[j]->sign[k] != unitPredicateIdSign[i]) { //conflicting atom in clause, remove it CNF[j]->removeAtom(k); isCNFChanged = true; k--; //check if we get an empty clause if(CNF[j]->atoms.size()==0 && !CNF[j]->satisfied) return LogDouble(0,false); } else { //set clause to satisfied CNF[j]->satisfied = true; //satisfied atom in clause, remove it CNF[j]->removeAtom(k); k--; } } } } } if(!isCNFChanged) break; } return val; }
LogDouble LPTPSearch::weightedModelCountApprox(vector<WClause*>& CNF) { double satPercent1 = 0; int cnfStatus=CheckCNFSatisfied(CNF,satPercent1); if( cnfStatus==0) { cleanup(CNF); return LogDouble(0,false); } vector<int> powerFactors; vector<bool> isDecomposedCNF; vector<vector<WClause*> > decomposedList; LClusterUtil::seperateDisjointCNF(CNF,decomposedList); //CNF can be cleaned up since split into clusters cleanup(CNF); LogDouble totalVal(1,false); for(int t=0;t<decomposedList.size();t++) { int powerFactor; bool isDecomposed = decomposeCNF(decomposedList[t],powerFactor); if(isDecomposed) { #ifdef __DEBUG_PRINT__ LvrMLN::print(decomposedList[t],"DECOMPOSED"); #endif //use power rule LogDouble mcnt = weightedModelCountApprox(decomposedList[t]); LogDouble val = LogDouble(1,false); LogDouble::LDPower(mcnt,powerFactor,val); totalVal = totalVal*val; continue; } else { //normalizer->normalizeClauses(decomposedList[t]); #ifdef __DEBUG_PRINT__ LvrMLN::print(decomposedList[t],"NORMALIZED"); #endif LogDouble unitPropVal = extensions->unitPropagation(decomposedList[t]); if(unitPropVal.is_zero) { cleanupItems(decomposedList,t); #ifdef __DEBUG_PRINT__ cout<<"***********UnitPROP***********"<<endl; cout<<"{}"<<endl; cout<<"************UNITProp***************"<<endl; #endif return unitPropVal; } else { totalVal = totalVal*unitPropVal; } #ifdef __DEBUG_PRINT__ LvrMLN::print(decomposedList[t],"UNITPROP"); #endif double satPercent = 0; int status=CheckCNFSatisfied(decomposedList[t],satPercent); LogDouble wt = LogDouble(); if(status == 1) { totalVal = totalVal * CNFWeight(decomposedList[t]); cleanup(decomposedList[t]); continue; } else if( status==0) { cleanup(decomposedList[t]); return LogDouble(0,false); } vector<vector<WClause*> > tempCNFList; Atom* atom = heuristics->getAtomToSplit(decomposedList[t]); #ifdef __DEBUG_PRINT__ cout<<"Splitting on Atom "; atom->print(); cout<<")"<<endl; #endif #ifdef __DEBUG_PRINT__ LvrMLN::print(decomposedList[t],"SPLIT-INPUT"); #endif int completedCount = 0; vector<int> reductionFactor; int numGroundings = atom->getNumberOfGroundings(); vector<bool> completedGroups(numGroundings + 1); while(1) { int numTrue; LogDouble probOfSample; splitter->doApproxSplit(decomposedList[t], atom, numGroundings, completedGroups, completedCount, probOfSample, numTrue, tempCNFList); //cout<<"here"<<endl; int numFalse = numGroundings - numTrue; //just 1 sample collected LogDouble pos = LogDouble(1,false); LogDouble neg = LogDouble(1,false); LogDouble::LDPower(atom->symbol->pweight,numTrue,pos); LogDouble::LDPower(atom->symbol->nweight,numFalse,neg); LogDouble binCoeff = LogDouble::Binomial(numTrue+numFalse,numTrue); normalizer->normalizeClauses(tempCNFList.back(),true,false); LogDouble mcnt = weightedModelCountApprox(tempCNFList.back()); cleanup(tempCNFList.back()); tempCNFList.pop_back(); if(mcnt.is_zero) { //cout<<"backtrack!"<<endl; completedGroups[numTrue] = true; completedCount++; if(completedCount == completedGroups.size()) { wt = 0; break; } else continue; } wt+=binCoeff*pos*neg*mcnt/probOfSample; break; } #ifdef __DEBUG_PRINT__ cout<<"Wt="<<wt<<endl; #endif cleanup(decomposedList[t]); if(wt.is_zero) { cleanupItems(decomposedList,t+1); return wt; } totalVal = totalVal*wt; } } return totalVal; }
LogDouble LPTPSearch::weightedModelCount(vector<WClause*>& CNF,LvrPTPNode* parent,int parentBranchNo) { double satPercent1 = 0; int cnfStatus=CheckCNFSatisfied(CNF,satPercent1); if( cnfStatus==0) { if(LvrQueryUpdater::isInstanceCreated()) lvrptpSearchTree->createNewNode(ELEAF,parent,parentBranchNo); cleanup(CNF); return LogDouble(0,false); } vector<int> powerFactors; vector<bool> isDecomposedCNF; vector<vector<WClause*> > decomposedList; LClusterUtil::seperateDisjointCNF(CNF,decomposedList); //CNF can be cleaned up since split into clusters cleanup(CNF); LogDouble totalVal(1,false); LvrPTPNode* djnode = NULL; if(LvrQueryUpdater::isInstanceCreated()) djnode = lvrptpSearchTree->createNewNode(EAND,parent,parentBranchNo); for(int t=0;t<decomposedList.size();t++) { int dum=1; bool isDecomposed=false; int powerFactor; isDecomposed = decomposeCNF(decomposedList[t],powerFactor); if(isDecomposed) { #ifdef __DEBUG_PRINT__ LvrMLN::print(decomposedList[t],"DECOMPOSED"); #endif //use power rule LvrPTPNode* decompNode = NULL; if(LvrQueryUpdater::isInstanceCreated()) { decompNode = lvrptpSearchTree->createNewNode(EPOWER,djnode,t); decompNode->powerFactor = powerFactor; } LogDouble mcnt = weightedModelCount(decomposedList[t],decompNode,0); LogDouble val = LogDouble(1,false); LogDouble::LDPower(mcnt,powerFactor,val); totalVal = totalVal*val; if(LvrQueryUpdater::isInstanceCreated()) decompNode->nodeValue = val; continue; } else { //normalizer->normalizeClauses(decomposedList[t]); //do unit propagation #ifdef __DEBUG_PRINT1__ LvrMLN::print(decomposedList[t],"NORMALIZED"); #endif if(dounitpropagate) { LogDouble unitPropVal; if(LvrQueryUpdater::isInstanceCreated()) unitPropVal = extensions->unitPropagation(decomposedList[t],true); else unitPropVal = extensions->unitPropagation(decomposedList[t]); if(unitPropVal.is_zero) { cleanupItems(decomposedList,t); #ifdef __DEBUG_PRINT__ cout<<"***********UnitPROP***********"<<endl; cout<<"{}"<<endl; cout<<"************UNITProp***************"<<endl; #endif if(LvrQueryUpdater::isInstanceCreated()) lvrptpSearchTree->createNewNode(ELEAF,djnode,t); return unitPropVal; } else { totalVal = totalVal*unitPropVal; } } #ifdef __DEBUG_PRINT__ LvrMLN::print(decomposedList[t],"UNITPROP"); #endif double satPercent = 0; int status=CheckCNFSatisfied(decomposedList[t],satPercent); //int status=CheckCNFSatisfiedWithQueries(decomposedList[t]); LogDouble wt = LogDouble(); if(status == 1) { if(LvrQueryUpdater::isInstanceCreated()) { set<int>* dontcarequeries = new set<int>(); //if the leaf contains any query atoms (they become dont care), store the hash representations of these LogDouble wt = CNFWeight(decomposedList[t],dontcarequeries); LvrPTPNode* leaf = lvrptpSearchTree->createNewNode(ELEAF,djnode,t); leaf->dontCareQueries = dontcarequeries; leaf->nodeValue = wt; totalVal = totalVal * wt; } else { totalVal = totalVal * CNFWeight(decomposedList[t]); } cleanup(decomposedList[t]); continue; } vector<vector<WClause*> > tempCNFList; Atom* atom = heuristics->getAtomToSplit(decomposedList[t]); #ifdef __DEBUG_PRINT__ cout<<"Splitting on Atom "; atom->print(); cout<<endl; #endif bool cached = false; if(satPercent1 < 0.75) { cached = extensions->getFromCache(decomposedList[t],wt); } if(!cached) { //check for self joins bool selfJoined = false; for(int m=0;m<decomposedList[t].size();m++) { if(decomposedList[t].at(m)->isSelfJoinedOnAtom(atom)) { selfJoined = true; break; } } vector<LogDouble> branchWeights; if(atom->isConstant()) { int idToUse = id++; //propositional atom if(!selfJoined) PropositionalResolution::doPropositionalSplit(decomposedList[t],atom,tempCNFList); else PropositionalResolution::doPropositionalSplitSelfJoins(decomposedList[t],atom,tempCNFList); LogDouble symPosWt = atom->symbol->pweight; LogDouble symNegWt = atom->symbol->nweight; LvrPTPNode* splitNode = NULL; if(LvrQueryUpdater::isInstanceCreated()) { splitNode = lvrptpSearchTree->createNewNode(ESPLITTER,djnode,t); splitNode->atom = LvrMLN::create_new_atom(atom); } LogDouble w1 = symNegWt*weightedModelCount(tempCNFList[0],splitNode,0); LogDouble w2 = symPosWt*weightedModelCount(tempCNFList[1],splitNode,1); //cleanup(decomposedList[t]); wt += w1 + w2; if(LvrQueryUpdater::isInstanceCreated()) { splitNode->branchWeights.push_back(symNegWt); splitNode->branchWeights.push_back(symPosWt); splitNode->nodeValue = w1+w2; } cleanup(tempCNFList[0]); cleanup(tempCNFList[1]); tempCNFList.clear(); } else //first order atom { //check in cache int singletonIndex; bool singleton = atom->isSingletonAtom(singletonIndex); bool nonpoly = false; if(!singleton) nonpoly = true; else if(selfJoined) { //check for blocking rule bool blocked = LRulesUtil::isBlocked(atom,singletonIndex,decomposedList[t]); if(!blocked) nonpoly=true; } //lifted domain reduction if(!nonpoly) { /* splitter->doLiftedSplit(decomposedList[t],atom,tempCNFList,singletonIndex); LogDouble symPosWt = atom->symbol->pweight; LogDouble symNegWt = atom->symbol->nweight; int domSize = atom->terms[singletonIndex]->domain.size(); //int i = tempCNFList.size()-1; LvrPTPNode* splitNode = NULL; if(LvrQueryUpdater::isInstanceCreated()) { splitNode = lvrptpSearchTree->createNewNode(ESPLITTER,djnode,t); splitNode->atom = LvrMLN::create_new_atom(atom); branchWeights.clear(); branchWeights.resize(tempCNFList.size()); } LogDouble norm; for(unsigned int jj=0;jj<tempCNFList.size();jj++) { LogDouble pos = LogDouble(1,false); LogDouble neg = LogDouble(1,false); LogDouble::LDPower(symPosWt,jj,pos); LogDouble::LDPower(symNegWt,domSize-jj,neg); LogDouble binCoeff = LogDouble::Binomial(domSize,jj); normalizer->normalizeClauses(tempCNFList[jj],true,false); LogDouble mcnt = weightedModelCount(tempCNFList[jj],splitNode,jj); wt+=binCoeff*pos*neg*mcnt; if(LvrQueryUpdater::isInstanceCreated()) branchWeights[jj] = pos*neg; norm += binCoeff*pos*neg*mcnt; } while(!tempCNFList.empty()) { cleanup(tempCNFList.back()); tempCNFList.pop_back(); } */ Atom* tmpAtom = LvrMLN::create_new_atom(atom); LogDouble norm; LogDouble symPosWt = atom->symbol->pweight; LogDouble symNegWt = atom->symbol->nweight; int domSize = atom->terms[singletonIndex]->domain.size(); LvrPTPNode* splitNode = NULL; if(LvrQueryUpdater::isInstanceCreated()) { splitNode = lvrptpSearchTree->createNewNode(ESPLITTER,djnode,t); splitNode->atom = LvrMLN::create_new_atom(atom); branchWeights.clear(); branchWeights.resize(domSize+1); } for(int jj=0;jj<=domSize;jj++) { LogDouble pos = LogDouble(1,false); LogDouble neg = LogDouble(1,false); LogDouble::LDPower(symPosWt,jj,pos); LogDouble::LDPower(symNegWt,domSize-jj,neg); LogDouble binCoeff = LogDouble::Binomial(domSize,jj); vector<WClause*> lvClausesCopy; LvrMLN::copyAllClauses(decomposedList[t],lvClausesCopy); LvrSingletonNormPropagation::propagateNormalizedCNF(lvClausesCopy,tmpAtom,singletonIndex,jj); LogDouble mcnt = weightedModelCount(lvClausesCopy,splitNode,jj); cleanup(lvClausesCopy); wt+=binCoeff*pos*neg*mcnt; if(LvrQueryUpdater::isInstanceCreated()) branchWeights[jj] = pos*neg; norm += binCoeff*pos*neg*mcnt; } delete tmpAtom; if(LvrQueryUpdater::isInstanceCreated()) { splitNode->nodeValue = norm; splitNode->branchWeights = branchWeights; } } else //NON-Singleton or selfjoined atom,non polynomial grounding { cout<<"Non polynomial splitting atom encountered...may take a long time to compute"<<endl; vector<WClause*> groundCNF; vector<vector<int> > allGroundings; int numGroundings; splitter->doFullGrounding(decomposedList[t],atom,groundCNF,allGroundings,numGroundings); /* //Do resolution in chunks to avoid memory allocation problems int startnum = 0; int chunkSize = SPLITCHUNKSIZE; bool done = false; LogDouble symPosWt = atom->symbol->pweight; LogDouble symNegWt = atom->symbol->nweight; int atomId = atom->symbol->id; while(!done) { vector<vector<WClause*> > resolvedCNFList; //resolve exactly chunksize truth assignments splitter->doCompleteSplitInChunks(groundCNF,atomId, allGroundings, numGroundings, resolvedCNFList,startnum, chunkSize,done); int endnum = startnum + resolvedCNFList.size()-1; while(!resolvedCNFList.empty()) { //get the number of 1's in the truth assignment int n = endnum; int count=0; while(n) { count++; n &= (n-1); } LogDouble pos = LogDouble(1,false); LogDouble neg = LogDouble(1,false); LogDouble::LDPower(symPosWt,count,pos); LogDouble::LDPower(symNegWt,numGroundings-count,neg); normalizer->normalizeClauses(resolvedCNFList.back(),true,false); LogDouble mcnt = weightedModelCount(resolvedCNFList.back(),0,endnum); cleanup(resolvedCNFList.back()); resolvedCNFList.pop_back(); endnum--; wt=wt+pos*neg*mcnt; } //increment the start position for next chunk startnum += chunkSize; } */ vector<vector<WClause*> > resolvedCNFList; bool done = false; LogDouble symPosWt = atom->symbol->pweight; LogDouble symNegWt = atom->symbol->nweight; int atomId = atom->symbol->id; splitter->doCompleteSplitInChunks(groundCNF,atomId, allGroundings, numGroundings, resolvedCNFList,0, pow(2.0,numGroundings),done); LvrPTPNode* splitNode = NULL; if(LvrQueryUpdater::isInstanceCreated()) { splitNode = lvrptpSearchTree->createNewNode(ESPLITTER,djnode,t); splitNode->atom = LvrMLN::create_new_atom(atom); branchWeights.clear(); branchWeights.resize(resolvedCNFList.size()); } LogDouble norm; for(unsigned int jj=0;jj<resolvedCNFList.size();jj++) { //get the number of 1's in the truth assignment int n = jj; int count=0; while(n) { count++; n &= (n-1); } LogDouble pos = LogDouble(1,false); LogDouble neg = LogDouble(1,false); LogDouble::LDPower(symPosWt,count,pos); LogDouble::LDPower(symNegWt,numGroundings-count,neg); normalizer->normalizeClauses(resolvedCNFList[jj],true,false); LogDouble mcnt = weightedModelCount(resolvedCNFList[jj],splitNode,jj); wt=wt+pos*neg*mcnt; if(LvrQueryUpdater::isInstanceCreated()) branchWeights[jj] = pos*neg; norm += pos*neg*mcnt; } while(!resolvedCNFList.empty()) { cleanup(resolvedCNFList.back()); resolvedCNFList.pop_back(); } if(LvrQueryUpdater::isInstanceCreated()) { splitNode->nodeValue = norm; splitNode->branchWeights = branchWeights; } cleanup(groundCNF); }//non singleton }//first order atom if(satPercent < 0.75) extensions->storeToCache(decomposedList[t],wt); }//not cached #ifdef __DEBUG_PRINT__ cout<<"Wt="<<wt<<endl; #endif cleanup(decomposedList[t]); if(wt.is_zero) { if(LvrQueryUpdater::isInstanceCreated()) lvrptpSearchTree->createNewNode(ELEAF,djnode,t); cleanupItems(decomposedList,t+1); return wt; } totalVal = totalVal*wt; }//end split step }//end for if(LvrQueryUpdater::isInstanceCreated()) djnode->nodeValue = totalVal; return totalVal; }
void LProposalDistributionElement::sample(LogDouble& prob,vector<int>& sampledValues, int domainSize) { //print(); prob = LogDouble(1,false); sampledValues.clear(); sampledValues.resize(proposalTables.size()); int index = 0; //from the current parent's value get the index ofdistribution to sample if(parents.size()==0) { index=0; } else { vector<int> parentValues; vector<int> parentSizes; for(int i=0;i<parents.size();i++) { parentValues.push_back(parents[i]->nTrueValues); parentSizes.push_back(parents[i]->atom->getNumberOfGroundings()); } //decode index = parentValues[parentValues.size()-1]; for(int j=parentSizes.size()-2;j>=0;j--) { for(unsigned int k=j+1;k<parentSizes.size();k++) index += parentValues[j]*parentSizes[k]; } } if(index < 0) index=0; int totalValue = 0; LogDouble probToUpdate(1,false); for(unsigned int i=0;i<proposalTables.size();i++) { //check for mismatch double tableSize = proposalTables[i]->getTableSize(index); if(domainSize+1 != tableSize && domainSize > 0) { if(domainSize+1 < tableSize) { //proposal stored for a variant of the atom //need to dynamically create a modified proposal and sample from it int difference = tableSize - (domainSize + 1); vector<LogDouble> currProposal; vector<LogDouble> prevProposal; double N = tableSize; for(unsigned int jj=0;jj<proposalTables[i]->distribution[index].size();jj++) { prevProposal.push_back(proposalTables[i]->distribution[index][jj]); } for(int t=0;t<difference;t++) { N = prevProposal.size(); currProposal.clear(); currProposal.resize(prevProposal.size()-1); for(unsigned int p=0;p<currProposal.size();p++) { LogDouble c1((N-(double)p)/N,false); LogDouble c2(((double)p+1.0)/N,false); currProposal[p] = c1*prevProposal[p]+c2*prevProposal[p+1]; } prevProposal.clear(); for(unsigned int p=0;p<currProposal.size();p++) { prevProposal.push_back(currProposal[p]); } } //sample from new distribution vector<LogDouble> cdf(currProposal.size()); cdf[0] = currProposal[0]; for(unsigned int ii=1;ii<currProposal.size()-1;ii++) { cdf[ii] = cdf[ii-1]+currProposal[ii]; } cdf[cdf.size()-1] = LogDouble(1,false); double u = LvRandomGenUtil::Instance()->getNormRand(); LogDouble lu(u,false); int nTrues = lower_bound(cdf.begin(),cdf.end(),lu) - cdf.begin(); totalValue += nTrues; probToUpdate *= currProposal[nTrues]; sampledValues[i] = nTrues; prob *= currProposal[nTrues]; //update the appropriate counter proposalTables[i]->adaptiveMLECounter[index].at(nTrues)++; proposalTables[i]->totalSamplesCollected[index]++; } } else { //sample from original proposal distribution proposalTables[i]->sampleDistribution(index); prob *= proposalTables[i]->sampledProbability; sampledValues[i] = proposalTables[i]->sampledValue; probToUpdate *= proposalTables[i]->sampledProbability; totalValue += proposalTables[i]->sampledValue; } } this->probability = probToUpdate; this->nTrueValues = totalValue; }
WClause* LiftedAlgsConvertor::convertClauseToLifted(Clause* clause, const Domain* domain, vector<PredicateSymbol*>& symbolsToAdd,bool& containsGroundedClause) { const Array<Predicate*>* preds = clause->getPredicates(); map<int,LvrTerm*> mapOfTerms; WClause* nClause = new WClause(); nClause->atoms = vector<Atom*>(preds->size()); nClause->sign = vector<bool>(preds->size()); nClause->weight = LogDouble(clause->getWt(),false); set<int> completedIds; for (int i = 0; i < preds->size(); i++) { nClause->sign[i] = !((*preds)[i]->getSense()); int predicateId = (*preds)[i]->getId(); vector<int> var_types((*preds)[i]->getNumTerms()); string symbolName((*preds)[i]->getName()); PredicateSymbol* pSymbol = new PredicateSymbol(predicateId,symbolName,var_types,LogDouble(1,false),LogDouble(1,false),predicateId); const PredicateTemplate *ptemplate = (*preds)[i]->getTemplate(); vector<LvrTerm*> atomTerms((*preds)[i]->getNumTerms()); for (int termno = 0; termno < (*preds)[i]->getNumTerms(); termno++) { const Term* term = (*preds)[i]->getTerm(termno); if(term->getType()==Term::CONSTANT) { int id = term->getId(); vector<int> domValues(1); domValues[0] = id; LvrTerm* lvrTerm = new LvrTerm(0,domValues); atomTerms[termno]=lvrTerm; //contains a "+" in the term containsGroundedClause=true; continue; } int varId = term->getId(); map<int,LvrTerm*>::iterator mapIt = mapOfTerms.find(varId); if(mapIt==mapOfTerms.end()) { //new term, add it int varTypeId = ptemplate->getTermTypeAsInt(termno); const Array<int>* constants = domain->getConstantsByType(varTypeId); vector<int> domValues; for(unsigned int j=0;j<constants->size();j++) { domValues.push_back((*constants)[j]); } LvrTerm* lvrTerm = new LvrTerm(0,domValues); mapOfTerms.insert(pair<int,LvrTerm*> (varId,lvrTerm)); atomTerms[termno]=lvrTerm; } else { //use existing term atomTerms[termno] = mapIt->second; } } //sort the domains of all terms for(unsigned int jj=0;jj<atomTerms.size();jj++) sort(atomTerms[jj]->domain.begin(),atomTerms[jj]->domain.end()); Atom* atom = new Atom(pSymbol,atomTerms); nClause->atoms[i] = atom; if(completedIds.count(pSymbol->id) == 0) { //ADD TO LvrMLN PredicateSymbol* nSymbol = new PredicateSymbol(predicateId,symbolName,var_types,LogDouble(1,false),LogDouble(1,false),predicateId); symbolsToAdd.push_back(nSymbol); } } return nClause; }