コード例 #1
0
	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;
		}	
	}
コード例 #2
0
ファイル: queryupdater.cpp プロジェクト: Artemid/alchemy-2
/*
//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);
			}
		}
	}
}
コード例 #3
0
ファイル: ptpsearch.cpp プロジェクト: Artemid/alchemy-2
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;
}
コード例 #4
0
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;
}
コード例 #5
0
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);
	}
}
コード例 #6
0
ファイル: logdouble.cpp プロジェクト: Artemid/alchemy-2
LogDouble LogDouble::operator*(const LogDouble& other) const {
	if (is_zero || other.is_zero)
	{
		return LogDouble();
	}
	LogDouble out(other);
	out.value += value;
	return out;
}
コード例 #7
0
ファイル: queryupdater.cpp プロジェクト: Artemid/alchemy-2
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);
	}
}
コード例 #8
0
ファイル: logdouble.cpp プロジェクト: Artemid/alchemy-2
LogDouble LogDouble::operator/(const LogDouble& other) const {
	if (is_zero || other.is_zero)
	{
		return LogDouble();
	}
	LogDouble out(value);
	out.value -= other.value;
	return out;
}
コード例 #9
0
	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;
		}
	}
コード例 #10
0
ファイル: TranscriptionLayer.hpp プロジェクト: hanz513/RNNLIB
		//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]);
			}
コード例 #11
0
ファイル: logdouble.cpp プロジェクト: Artemid/alchemy-2
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;
}
コード例 #12
0
ファイル: ptpsearch.cpp プロジェクト: Artemid/alchemy-2
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;
}
コード例 #13
0
ファイル: queryupdater.cpp プロジェクト: Artemid/alchemy-2
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);
	}
}
コード例 #14
0
ファイル: queryupdater.cpp プロジェクト: Artemid/alchemy-2
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);
	}
}
コード例 #15
0
ファイル: logdouble.cpp プロジェクト: Artemid/alchemy-2
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;
	
}
コード例 #16
0
ファイル: queryupdater.cpp プロジェクト: Artemid/alchemy-2
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);
	}
}
コード例 #17
0
	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]++;
	}
コード例 #18
0
ファイル: extensions.cpp プロジェクト: JIELOGAN/alchemy-2
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;
}
コード例 #19
0
ファイル: ptpsearch.cpp プロジェクト: Artemid/alchemy-2
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;
}
コード例 #20
0
ファイル: ptpsearch.cpp プロジェクト: Artemid/alchemy-2
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;
}
コード例 #21
0
	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;
	}
コード例 #22
0
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;
}