diff --git a/packages/CLPBN/horus2/BayesBall.cpp b/packages/CLPBN/horus2/BayesBall.cpp deleted file mode 100644 index 0fac25056..000000000 --- a/packages/CLPBN/horus2/BayesBall.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include -#include - -#include -#include -#include - -#include "BayesBall.h" -#include "Util.h" - - -FactorGraph* -BayesBall::getMinimalFactorGraph (const VarIds& queryIds) -{ - assert (fg_.bayesianFactors()); - Scheduling scheduling; - for (size_t i = 0; i < queryIds.size(); i++) { - assert (dag_.getNode (queryIds[i])); - BBNode* n = dag_.getNode (queryIds[i]); - scheduling.push (ScheduleInfo (n, false, true)); - } - - while (!scheduling.empty()) { - ScheduleInfo& sch = scheduling.front(); - BBNode* n = sch.node; - n->setAsVisited(); - if (n->hasEvidence() == false && sch.visitedFromChild) { - if (n->isMarkedOnTop() == false) { - n->markOnTop(); - scheduleParents (n, scheduling); - } - if (n->isMarkedOnBottom() == false) { - n->markOnBottom(); - scheduleChilds (n, scheduling); - } - } - if (sch.visitedFromParent) { - if (n->hasEvidence() && n->isMarkedOnTop() == false) { - n->markOnTop(); - scheduleParents (n, scheduling); - } - if (n->hasEvidence() == false && n->isMarkedOnBottom() == false) { - n->markOnBottom(); - scheduleChilds (n, scheduling); - } - } - scheduling.pop(); - } - - FactorGraph* fg = new FactorGraph(); - constructGraph (fg); - return fg; -} - - - -void -BayesBall::constructGraph (FactorGraph* fg) const -{ - const FacNodes& facNodes = fg_.facNodes(); - for (size_t i = 0; i < facNodes.size(); i++) { - const BBNode* n = dag_.getNode ( - facNodes[i]->factor().argument (0)); - if (n->isMarkedOnTop()) { - fg->addFactor (facNodes[i]->factor()); - } else if (n->hasEvidence() && n->isVisited()) { - VarIds varIds = { facNodes[i]->factor().argument (0) }; - Ranges ranges = { facNodes[i]->factor().range (0) }; - Params params (ranges[0], LogAware::noEvidence()); - params[n->getEvidence()] = LogAware::withEvidence(); - fg->addFactor (Factor (varIds, ranges, params)); - } - } - const VarNodes& varNodes = fg_.varNodes(); - for (size_t i = 0; i < varNodes.size(); i++) { - if (varNodes[i]->hasEvidence()) { - VarNode* vn = fg->getVarNode (varNodes[i]->varId()); - if (vn) { - vn->setEvidence (varNodes[i]->getEvidence()); - } - } - } -} - diff --git a/packages/CLPBN/horus2/BayesBall.h b/packages/CLPBN/horus2/BayesBall.h deleted file mode 100644 index 4efbd2ed1..000000000 --- a/packages/CLPBN/horus2/BayesBall.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef HORUS_BAYESBALL_H -#define HORUS_BAYESBALL_H - -#include -#include -#include -#include - -#include "FactorGraph.h" -#include "BayesBallGraph.h" -#include "Horus.h" - -using namespace std; - - -struct ScheduleInfo -{ - ScheduleInfo (BBNode* n, bool vfp, bool vfc) : - node(n), visitedFromParent(vfp), visitedFromChild(vfc) { } - - BBNode* node; - bool visitedFromParent; - bool visitedFromChild; -}; - - -typedef queue> Scheduling; - - -class BayesBall -{ - public: - BayesBall (FactorGraph& fg) - : fg_(fg) , dag_(fg.getStructure()) - { - dag_.clear(); - } - - FactorGraph* getMinimalFactorGraph (const VarIds&); - - static FactorGraph* getMinimalFactorGraph (FactorGraph& fg, VarIds vids) - { - BayesBall bb (fg); - return bb.getMinimalFactorGraph (vids); - } - - private: - - void constructGraph (FactorGraph* fg) const; - - void scheduleParents (const BBNode* n, Scheduling& sch) const; - - void scheduleChilds (const BBNode* n, Scheduling& sch) const; - - FactorGraph& fg_; - - BayesBallGraph& dag_; -}; - - - -inline void -BayesBall::scheduleParents (const BBNode* n, Scheduling& sch) const -{ - const vector& ps = n->parents(); - for (vector::const_iterator it = ps.begin(); - it != ps.end(); ++it) { - sch.push (ScheduleInfo (*it, false, true)); - } -} - - - -inline void -BayesBall::scheduleChilds (const BBNode* n, Scheduling& sch) const -{ - const vector& cs = n->childs(); - for (vector::const_iterator it = cs.begin(); - it != cs.end(); ++it) { - sch.push (ScheduleInfo (*it, true, false)); - } -} - -#endif // HORUS_BAYESBALL_H - diff --git a/packages/CLPBN/horus2/BayesBallGraph.cpp b/packages/CLPBN/horus2/BayesBallGraph.cpp deleted file mode 100644 index 36fcbb5ee..000000000 --- a/packages/CLPBN/horus2/BayesBallGraph.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include -#include - -#include -#include -#include - -#include "BayesBallGraph.h" -#include "Util.h" - - -void -BayesBallGraph::addNode (BBNode* n) -{ - assert (Util::contains (varMap_, n->varId()) == false); - nodes_.push_back (n); - varMap_[n->varId()] = n; -} - - - -void -BayesBallGraph::addEdge (VarId vid1, VarId vid2) -{ - unordered_map::iterator it1; - unordered_map::iterator it2; - it1 = varMap_.find (vid1); - it2 = varMap_.find (vid2); - assert (it1 != varMap_.end()); - assert (it2 != varMap_.end()); - it1->second->addChild (it2->second); - it2->second->addParent (it1->second); -} - - - -const BBNode* -BayesBallGraph::getNode (VarId vid) const -{ - unordered_map::const_iterator it; - it = varMap_.find (vid); - return it != varMap_.end() ? it->second : 0; -} - - - -BBNode* -BayesBallGraph::getNode (VarId vid) -{ - unordered_map::const_iterator it; - it = varMap_.find (vid); - return it != varMap_.end() ? it->second : 0; -} - - - -void -BayesBallGraph::setIndexes (void) -{ - for (size_t i = 0; i < nodes_.size(); i++) { - nodes_[i]->setIndex (i); - } -} - - - -void -BayesBallGraph::clear (void) -{ - for (size_t i = 0; i < nodes_.size(); i++) { - nodes_[i]->clear(); - } -} - - - -void -BayesBallGraph::exportToGraphViz (const char* fileName) -{ - ofstream out (fileName); - if (!out.is_open()) { - cerr << "Error: couldn't open file '" << fileName << "'." ; - return; - } - out << "digraph {" << endl; - out << "ranksep=1" << endl; - for (size_t i = 0; i < nodes_.size(); i++) { - out << nodes_[i]->varId() ; - out << " [" ; - out << "label=\"" << nodes_[i]->label() << "\"" ; - if (nodes_[i]->hasEvidence()) { - out << ",style=filled, fillcolor=yellow" ; - } - out << "]" << endl; - } - for (size_t i = 0; i < nodes_.size(); i++) { - const vector& childs = nodes_[i]->childs(); - for (size_t j = 0; j < childs.size(); j++) { - out << nodes_[i]->varId() << " -> " << childs[j]->varId(); - out << " [style=bold]" << endl ; - } - } - out << "}" << endl; - out.close(); -} - diff --git a/packages/CLPBN/horus2/BayesBallGraph.h b/packages/CLPBN/horus2/BayesBallGraph.h deleted file mode 100644 index 72a0f90d0..000000000 --- a/packages/CLPBN/horus2/BayesBallGraph.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef HORUS_BAYESBALLGRAPH_H -#define HORUS_BAYESBALLGRAPH_H - -#include -#include -#include -#include - -#include "Var.h" -#include "Horus.h" - -using namespace std; - -class BBNode : public Var -{ - public: - BBNode (Var* v) : Var (v) , visited_(false), - markedOnTop_(false), markedOnBottom_(false) { } - - const vector& childs (void) const { return childs_; } - - vector& childs (void) { return childs_; } - - const vector& parents (void) const { return parents_; } - - vector& parents (void) { return parents_; } - - void addParent (BBNode* p) { parents_.push_back (p); } - - void addChild (BBNode* c) { childs_.push_back (c); } - - bool isVisited (void) const { return visited_; } - - void setAsVisited (void) { visited_ = true; } - - bool isMarkedOnTop (void) const { return markedOnTop_; } - - void markOnTop (void) { markedOnTop_ = true; } - - bool isMarkedOnBottom (void) const { return markedOnBottom_; } - - void markOnBottom (void) { markedOnBottom_ = true; } - - void clear (void) { visited_ = markedOnTop_ = markedOnBottom_ = false; } - - private: - bool visited_; - bool markedOnTop_; - bool markedOnBottom_; - - vector childs_; - vector parents_; -}; - - -class BayesBallGraph -{ - public: - BayesBallGraph (void) { } - - void addNode (BBNode* n); - - void addEdge (VarId vid1, VarId vid2); - - const BBNode* getNode (VarId vid) const; - - BBNode* getNode (VarId vid); - - bool empty (void) const { return nodes_.empty(); } - - void setIndexes (void); - - void clear (void); - - void exportToGraphViz (const char*); - - private: - vector nodes_; - - unordered_map varMap_; -}; - -#endif // HORUS_BAYESBALLGRAPH_H - diff --git a/packages/CLPBN/horus2/BeliefProp.cpp b/packages/CLPBN/horus2/BeliefProp.cpp deleted file mode 100644 index d96384cfd..000000000 --- a/packages/CLPBN/horus2/BeliefProp.cpp +++ /dev/null @@ -1,471 +0,0 @@ -#include -#include - -#include - -#include - -#include "BeliefProp.h" -#include "FactorGraph.h" -#include "Factor.h" -#include "Indexer.h" -#include "Horus.h" - - -BeliefProp::BeliefProp (const FactorGraph& fg) : GroundSolver (fg) -{ - runned_ = false; -} - - - -BeliefProp::~BeliefProp (void) -{ - for (size_t i = 0; i < varsI_.size(); i++) { - delete varsI_[i]; - } - for (size_t i = 0; i < facsI_.size(); i++) { - delete facsI_[i]; - } - for (size_t i = 0; i < links_.size(); i++) { - delete links_[i]; - } -} - - - -Params -BeliefProp::solveQuery (VarIds queryVids) -{ - assert (queryVids.empty() == false); - return queryVids.size() == 1 - ? getPosterioriOf (queryVids[0]) - : getJointDistributionOf (queryVids); -} - - - -void -BeliefProp::printSolverFlags (void) const -{ - stringstream ss; - ss << "belief propagation [" ; - ss << "schedule=" ; - typedef BpOptions::Schedule Sch; - switch (BpOptions::schedule) { - case Sch::SEQ_FIXED: ss << "seq_fixed"; break; - case Sch::SEQ_RANDOM: ss << "seq_random"; break; - case Sch::PARALLEL: ss << "parallel"; break; - case Sch::MAX_RESIDUAL: ss << "max_residual"; break; - } - ss << ",max_iter=" << Util::toString (BpOptions::maxIter); - ss << ",accuracy=" << Util::toString (BpOptions::accuracy); - ss << ",log_domain=" << Util::toString (Globals::logDomain); - ss << "]" ; - cout << ss.str() << endl; -} - - - -Params -BeliefProp::getPosterioriOf (VarId vid) -{ - if (runned_ == false) { - runSolver(); - } - assert (fg.getVarNode (vid)); - VarNode* var = fg.getVarNode (vid); - Params probs; - if (var->hasEvidence()) { - probs.resize (var->range(), LogAware::noEvidence()); - probs[var->getEvidence()] = LogAware::withEvidence(); - } else { - probs.resize (var->range(), LogAware::multIdenty()); - const BpLinks& links = ninf(var)->getLinks(); - if (Globals::logDomain) { - for (size_t i = 0; i < links.size(); i++) { - probs += links[i]->message(); - } - LogAware::normalize (probs); - Util::exp (probs); - } else { - for (size_t i = 0; i < links.size(); i++) { - probs *= links[i]->message(); - } - LogAware::normalize (probs); - } - } - return probs; -} - - - -Params -BeliefProp::getJointDistributionOf (const VarIds& jointVarIds) -{ - if (runned_ == false) { - runSolver(); - } - VarNode* vn = fg.getVarNode (jointVarIds[0]); - const FacNodes& facNodes = vn->neighbors(); - size_t idx = facNodes.size(); - for (size_t i = 0; i < facNodes.size(); i++) { - if (facNodes[i]->factor().contains (jointVarIds)) { - idx = i; - break; - } - } - if (idx == facNodes.size()) { - return getJointByConditioning (jointVarIds); - } - return getFactorJoint (facNodes[idx], jointVarIds); -} - - - -Params -BeliefProp::getFactorJoint ( - FacNode* fn, - const VarIds& jointVarIds) -{ - if (runned_ == false) { - runSolver(); - } - Factor res (fn->factor()); - const BpLinks& links = ninf(fn)->getLinks(); - for (size_t i = 0; i < links.size(); i++) { - Factor msg ({links[i]->varNode()->varId()}, - {links[i]->varNode()->range()}, - getVarToFactorMsg (links[i])); - res.multiply (msg); - } - res.sumOutAllExcept (jointVarIds); - res.reorderArguments (jointVarIds); - res.normalize(); - Params jointDist = res.params(); - if (Globals::logDomain) { - Util::exp (jointDist); - } - return jointDist; -} - - - -void -BeliefProp::runSolver (void) -{ - initializeSolver(); - nIters_ = 0; - while (!converged() && nIters_ < BpOptions::maxIter) { - nIters_ ++; - if (Globals::verbosity > 1) { - Util::printHeader (string ("Iteration ") + Util::toString (nIters_)); - } - switch (BpOptions::schedule) { - case BpOptions::Schedule::SEQ_RANDOM: - std::random_shuffle (links_.begin(), links_.end()); - // no break - case BpOptions::Schedule::SEQ_FIXED: - for (size_t i = 0; i < links_.size(); i++) { - calculateAndUpdateMessage (links_[i]); - } - break; - case BpOptions::Schedule::PARALLEL: - for (size_t i = 0; i < links_.size(); i++) { - calculateMessage (links_[i]); - } - for (size_t i = 0; i < links_.size(); i++) { - updateMessage(links_[i]); - } - break; - case BpOptions::Schedule::MAX_RESIDUAL: - maxResidualSchedule(); - break; - } - } - if (Globals::verbosity > 0) { - if (nIters_ < BpOptions::maxIter) { - cout << "Belief propagation converged in " ; - cout << nIters_ << " iterations" << endl; - } else { - cout << "The maximum number of iterations was hit, terminating..." ; - cout << endl; - } - cout << endl; - } - runned_ = true; -} - - - -void -BeliefProp::createLinks (void) -{ - const FacNodes& facNodes = fg.facNodes(); - for (size_t i = 0; i < facNodes.size(); i++) { - const VarNodes& neighbors = facNodes[i]->neighbors(); - for (size_t j = 0; j < neighbors.size(); j++) { - links_.push_back (new BpLink (facNodes[i], neighbors[j])); - } - } -} - - - -void -BeliefProp::maxResidualSchedule (void) -{ - if (nIters_ == 1) { - for (size_t i = 0; i < links_.size(); i++) { - calculateMessage (links_[i]); - SortedOrder::iterator it = sortedOrder_.insert (links_[i]); - linkMap_.insert (make_pair (links_[i], it)); - } - return; - } - - for (size_t c = 0; c < links_.size(); c++) { - if (Globals::verbosity > 1) { - cout << "current residuals:" << endl; - for (SortedOrder::iterator it = sortedOrder_.begin(); - it != sortedOrder_.end(); ++it) { - cout << " " << setw (30) << left << (*it)->toString(); - cout << "residual = " << (*it)->residual() << endl; - } - } - - SortedOrder::iterator it = sortedOrder_.begin(); - BpLink* link = *it; - if (link->residual() < BpOptions::accuracy) { - return; - } - updateMessage (link); - link->clearResidual(); - sortedOrder_.erase (it); - linkMap_.find (link)->second = sortedOrder_.insert (link); - - // update the messages that depend on message source --> destin - const FacNodes& factorNeighbors = link->varNode()->neighbors(); - for (size_t i = 0; i < factorNeighbors.size(); i++) { - if (factorNeighbors[i] != link->facNode()) { - const BpLinks& links = ninf(factorNeighbors[i])->getLinks(); - for (size_t j = 0; j < links.size(); j++) { - if (links[j]->varNode() != link->varNode()) { - calculateMessage (links[j]); - BpLinkMap::iterator iter = linkMap_.find (links[j]); - sortedOrder_.erase (iter->second); - iter->second = sortedOrder_.insert (links[j]); - } - } - } - } - if (Globals::verbosity > 1) { - Util::printDashedLine(); - } - } -} - - - -void -BeliefProp::calcFactorToVarMsg (BpLink* link) -{ - FacNode* src = link->facNode(); - const VarNode* dst = link->varNode(); - const BpLinks& links = ninf(src)->getLinks(); - // calculate the product of messages that were sent - // to factor `src', except from var `dst' - unsigned reps = 1; - unsigned msgSize = Util::sizeExpected (src->factor().ranges()); - Params msgProduct (msgSize, LogAware::multIdenty()); - if (Globals::logDomain) { - for (size_t i = links.size(); i-- > 0; ) { - if (links[i]->varNode() != dst) { - if (Constants::SHOW_BP_CALCS) { - cout << " message from " << links[i]->varNode()->label(); - cout << ": " ; - } - Util::apply_n_times (msgProduct, getVarToFactorMsg (links[i]), - reps, std::plus()); - if (Constants::SHOW_BP_CALCS) { - cout << endl; - } - } - reps *= links[i]->varNode()->range(); - } - } else { - for (size_t i = links.size(); i-- > 0; ) { - if (links[i]->varNode() != dst) { - if (Constants::SHOW_BP_CALCS) { - cout << " message from " << links[i]->varNode()->label(); - cout << ": " ; - } - Util::apply_n_times (msgProduct, getVarToFactorMsg (links[i]), - reps, std::multiplies()); - if (Constants::SHOW_BP_CALCS) { - cout << endl; - } - } - reps *= links[i]->varNode()->range(); - } - } - Factor result (src->factor().arguments(), - src->factor().ranges(), msgProduct); - result.multiply (src->factor()); - if (Constants::SHOW_BP_CALCS) { - cout << " message product: " << msgProduct << endl; - cout << " original factor: " << src->factor().params() << endl; - cout << " factor product: " << result.params() << endl; - } - result.sumOutAllExcept (dst->varId()); - if (Constants::SHOW_BP_CALCS) { - cout << " marginalized: " << result.params() << endl; - } - link->nextMessage() = result.params(); - LogAware::normalize (link->nextMessage()); - if (Constants::SHOW_BP_CALCS) { - cout << " curr msg: " << link->message() << endl; - cout << " next msg: " << link->nextMessage() << endl; - } -} - - - -Params -BeliefProp::getVarToFactorMsg (const BpLink* link) const -{ - const VarNode* src = link->varNode(); - Params msg; - if (src->hasEvidence()) { - msg.resize (src->range(), LogAware::noEvidence()); - msg[src->getEvidence()] = LogAware::withEvidence(); - } else { - msg.resize (src->range(), LogAware::one()); - } - if (Constants::SHOW_BP_CALCS) { - cout << msg; - } - BpLinks::const_iterator it; - const BpLinks& links = ninf (src)->getLinks(); - if (Globals::logDomain) { - for (it = links.begin(); it != links.end(); ++it) { - if (*it != link) { - msg += (*it)->message(); - } - if (Constants::SHOW_BP_CALCS) { - cout << " x " << (*it)->message(); - } - } - } else { - for (it = links.begin(); it != links.end(); ++it) { - if (*it != link) { - msg *= (*it)->message(); - } - if (Constants::SHOW_BP_CALCS) { - cout << " x " << (*it)->message(); - } - } - } - if (Constants::SHOW_BP_CALCS) { - cout << " = " << msg; - } - return msg; -} - - - -Params -BeliefProp::getJointByConditioning (const VarIds& jointVarIds) const -{ - return GroundSolver::getJointByConditioning ( - GroundSolverType::BP, fg, jointVarIds); -} - - - -void -BeliefProp::initializeSolver (void) -{ - const VarNodes& varNodes = fg.varNodes(); - varsI_.reserve (varNodes.size()); - for (size_t i = 0; i < varNodes.size(); i++) { - varsI_.push_back (new SPNodeInfo()); - } - const FacNodes& facNodes = fg.facNodes(); - facsI_.reserve (facNodes.size()); - for (size_t i = 0; i < facNodes.size(); i++) { - facsI_.push_back (new SPNodeInfo()); - } - createLinks(); - for (size_t i = 0; i < links_.size(); i++) { - FacNode* src = links_[i]->facNode(); - VarNode* dst = links_[i]->varNode(); - ninf (dst)->addBpLink (links_[i]); - ninf (src)->addBpLink (links_[i]); - } -} - - - -bool -BeliefProp::converged (void) -{ - if (links_.size() == 0) { - return true; - } - if (nIters_ == 0) { - return false; - } - if (Globals::verbosity > 2) { - cout << endl; - } - if (nIters_ == 1) { - if (Globals::verbosity > 1) { - cout << "no residuals" << endl << endl; - } - return false; - } - bool converged = true; - if (BpOptions::schedule == BpOptions::Schedule::MAX_RESIDUAL) { - double maxResidual = (*(sortedOrder_.begin()))->residual(); - if (maxResidual > BpOptions::accuracy) { - converged = false; - } else { - converged = true; - } - } else { - for (size_t i = 0; i < links_.size(); i++) { - double residual = links_[i]->residual(); - if (Globals::verbosity > 1) { - cout << links_[i]->toString() + " residual = " << residual << endl; - } - if (residual > BpOptions::accuracy) { - converged = false; - if (Globals::verbosity < 2) { - break; - } - } - } - if (Globals::verbosity > 1) { - cout << endl; - } - } - return converged; -} - - - -void -BeliefProp::printLinkInformation (void) const -{ - for (size_t i = 0; i < links_.size(); i++) { - BpLink* l = links_[i]; - cout << l->toString() << ":" << endl; - cout << " curr msg = " ; - cout << l->message() << endl; - cout << " next msg = " ; - cout << l->nextMessage() << endl; - cout << " residual = " << l->residual() << endl; - } -} - diff --git a/packages/CLPBN/horus2/BeliefProp.h b/packages/CLPBN/horus2/BeliefProp.h deleted file mode 100644 index 64a41d916..000000000 --- a/packages/CLPBN/horus2/BeliefProp.h +++ /dev/null @@ -1,188 +0,0 @@ -#ifndef HORUS_BELIEFPROP_H -#define HORUS_BELIEFPROP_H - -#include -#include -#include - -#include "GroundSolver.h" -#include "Factor.h" -#include "FactorGraph.h" -#include "Util.h" - -using namespace std; - - -class BpLink -{ - public: - BpLink (FacNode* fn, VarNode* vn) - { - fac_ = fn; - var_ = vn; - v1_.resize (vn->range(), LogAware::log (1.0 / vn->range())); - v2_.resize (vn->range(), LogAware::log (1.0 / vn->range())); - currMsg_ = &v1_; - nextMsg_ = &v2_; - residual_ = 0.0; - } - - virtual ~BpLink (void) { }; - - FacNode* facNode (void) const { return fac_; } - - VarNode* varNode (void) const { return var_; } - - const Params& message (void) const { return *currMsg_; } - - Params& nextMessage (void) { return *nextMsg_; } - - double residual (void) const { return residual_; } - - void clearResidual (void) { residual_ = 0.0; } - - void updateResidual (void) - { - residual_ = LogAware::getMaxNorm (v1_,v2_); - } - - virtual void updateMessage (void) - { - swap (currMsg_, nextMsg_); - } - - string toString (void) const - { - stringstream ss; - ss << fac_->getLabel(); - ss << " -- " ; - ss << var_->label(); - return ss.str(); - } - - protected: - FacNode* fac_; - VarNode* var_; - Params v1_; - Params v2_; - Params* currMsg_; - Params* nextMsg_; - double residual_; -}; - -typedef vector BpLinks; - - -class SPNodeInfo -{ - public: - void addBpLink (BpLink* link) { links_.push_back (link); } - const BpLinks& getLinks (void) { return links_; } - private: - BpLinks links_; -}; - - -class BeliefProp : public GroundSolver -{ - public: - BeliefProp (const FactorGraph&); - - virtual ~BeliefProp (void); - - Params solveQuery (VarIds); - - virtual void printSolverFlags (void) const; - - virtual Params getPosterioriOf (VarId); - - virtual Params getJointDistributionOf (const VarIds&); - - protected: - void runSolver (void); - - virtual void createLinks (void); - - virtual void maxResidualSchedule (void); - - virtual void calcFactorToVarMsg (BpLink*); - - virtual Params getVarToFactorMsg (const BpLink*) const; - - virtual Params getJointByConditioning (const VarIds&) const; - - public: - Params getFactorJoint (FacNode* fn, const VarIds&); - - protected: - SPNodeInfo* ninf (const VarNode* var) const - { - return varsI_[var->getIndex()]; - } - - SPNodeInfo* ninf (const FacNode* fac) const - { - return facsI_[fac->getIndex()]; - } - - void calculateAndUpdateMessage (BpLink* link, bool calcResidual = true) - { - if (Globals::verbosity > 2) { - cout << "calculating & updating " << link->toString() << endl; - } - calcFactorToVarMsg (link); - if (calcResidual) { - link->updateResidual(); - } - link->updateMessage(); - } - - void calculateMessage (BpLink* link, bool calcResidual = true) - { - if (Globals::verbosity > 2) { - cout << "calculating " << link->toString() << endl; - } - calcFactorToVarMsg (link); - if (calcResidual) { - link->updateResidual(); - } - } - - void updateMessage (BpLink* link) - { - link->updateMessage(); - if (Globals::verbosity > 2) { - cout << "updating " << link->toString() << endl; - } - } - - struct CompareResidual - { - inline bool operator() (const BpLink* link1, const BpLink* link2) - { - return link1->residual() > link2->residual(); - } - }; - - BpLinks links_; - unsigned nIters_; - vector varsI_; - vector facsI_; - bool runned_; - - typedef multiset SortedOrder; - SortedOrder sortedOrder_; - - typedef unordered_map BpLinkMap; - BpLinkMap linkMap_; - - private: - void initializeSolver (void); - - bool converged (void); - - virtual void printLinkInformation (void) const; -}; - -#endif // HORUS_BELIEFPROP_H - diff --git a/packages/CLPBN/horus2/ConstraintTree.cpp b/packages/CLPBN/horus2/ConstraintTree.cpp deleted file mode 100644 index 0546d0852..000000000 --- a/packages/CLPBN/horus2/ConstraintTree.cpp +++ /dev/null @@ -1,1174 +0,0 @@ -#include - -#include - -#include "ConstraintTree.h" -#include "Util.h" - - -void -CTNode::mergeSubtree (CTNode* n, bool updateLevels) -{ - if (updateLevels) { - updateChildLevels (n, level_ + 1); - } - CTChilds::iterator chIt = childs_.find (n); - if (chIt != childs_.end()) { - assert ((*chIt)->symbol() == n->symbol()); - const CTChilds& childsToAdd = n->childs(); - for (CTChilds::const_iterator it = childsToAdd.begin(); - it != childsToAdd.end(); ++ it) { - (*chIt)->mergeSubtree (*it, false); - } - delete n; - } else { - childs_.insert (n); - } -} - - - -void -CTNode::removeChild (CTNode* child) -{ - assert (childs_.contains (child)); - childs_.remove (child); -} - - - -void -CTNode::removeChilds (void) -{ - childs_.clear(); -} - - - -void -CTNode::removeAndDeleteChild (CTNode* child) -{ - removeChild (child); - CTNode::deleteSubtree (child); -} - - - -void -CTNode::removeAndDeleteAllChilds (void) -{ - for (CTChilds::const_iterator chIt = childs_.begin(); - chIt != childs_.end(); ++ chIt) { - deleteSubtree (*chIt); - } - childs_.clear(); -} - - - -SymbolSet -CTNode::childSymbols (void) const -{ - SymbolSet symbols; - for (CTChilds::const_iterator chIt = childs_.begin(); - chIt != childs_.end(); ++ chIt) { - symbols.insert ((*chIt)->symbol()); - } - return symbols; -} - - - -void -CTNode::updateChildLevels (CTNode* n, unsigned level) -{ - CTNodes stack; - stack.push_back (n); - n->setLevel (level); - while (stack.empty() == false) { - CTNode* node = stack.back(); - stack.pop_back(); - for (CTChilds::const_iterator chIt = node->childs().begin(); - chIt != node->childs().end(); ++ chIt) { - (*chIt)->setLevel (node->level() + 1); - } - stack.insert (stack.end(), node->childs().begin(), - node->childs().end()); - } -} - - - -CTNode* -CTNode::copySubtree (const CTNode* root1) -{ - if (root1->childs().empty()) { - return new CTNode (*root1); - } - CTNode* root2 = new CTNode (*root1); - typedef pair StackPair; - vector stack = { StackPair (root1, root2) }; - while (stack.empty() == false) { - const CTNode* n1 = stack.back().first; - CTNode* n2 = stack.back().second; - stack.pop_back(); - // cout << "n2 childs: " << n2->childs(); - // cout << "n1 childs: " << n1->childs(); - n2->childs().reserve (n1->nrChilds()); - stack.reserve (n1->nrChilds()); - for (CTChilds::const_iterator chIt = n1->childs().begin(); - chIt != n1->childs().end(); ++ chIt) { - CTNode* chCopy = new CTNode (**chIt); - n2->childs().insert_sorted (chCopy); - if ((*chIt)->nrChilds() != 0) { - stack.push_back (StackPair (*chIt, chCopy)); - } - } - } - return root2; -} - - - -void -CTNode::deleteSubtree (CTNode* n) -{ - assert (n); - const CTChilds& childs = n->childs(); - for (CTChilds::const_iterator chIt = childs.begin(); - chIt != childs.end(); ++ chIt) { - deleteSubtree (*chIt); - } - delete n; -} - - - -ostream& operator<< (ostream &out, const CTNode& n) -{ - out << "(" << n.level() << ") " ; - out << n.symbol(); - return out; -} - - - -ConstraintTree::ConstraintTree (unsigned nrLvs) -{ - for (unsigned i = 0; i < nrLvs; i++) { - logVars_.push_back (LogVar (i)); - } - root_ = new CTNode (0, 0); - logVarSet_ = LogVarSet (logVars_); -} - - - -ConstraintTree::ConstraintTree (const LogVars& logVars) -{ - root_ = new CTNode (0, 0); - logVars_ = logVars; - logVarSet_ = LogVarSet (logVars); -} - - - -ConstraintTree::ConstraintTree ( - const LogVars& logVars, - const Tuples& tuples) -{ - root_ = new CTNode (0, 0); - logVars_ = logVars; - logVarSet_ = LogVarSet (logVars); - for (size_t i = 0; i < tuples.size(); i++) { - addTuple (tuples[i]); - } -} - - - -ConstraintTree::ConstraintTree (vector> names) -{ - assert (names.empty() == false); - assert (names.front().empty() == false); - unsigned nrLvs = names[0].size(); - for (size_t i = 0; i < nrLvs; i++) { - logVars_.push_back (LogVar (i)); - } - root_ = new CTNode (0, 0); - logVarSet_ = LogVarSet (logVars_); - for (size_t i = 0; i < names.size(); i++) { - Tuple t; - for (size_t j = 0; j < names[i].size(); j++) { - assert (names[i].size() == nrLvs); - t.push_back (LiftedUtils::getSymbol (names[i][j])); - } - addTuple (t); - } -} - - - -ConstraintTree::ConstraintTree (const ConstraintTree& ct) -{ - *this = ct; -} - - - -ConstraintTree::~ConstraintTree (void) -{ - CTNode::deleteSubtree (root_); -} - - - -void -ConstraintTree::addTuple (const Tuple& tuple) -{ - CTNode* prevNode = root_; - for (size_t i = 0; i < tuple.size(); i++) { - CTChilds::const_iterator it = prevNode->findSymbol (tuple[i]); - if (it == prevNode->childs().end()) { - CTNode* newNode = new CTNode (tuple[i], i + 1); - prevNode->mergeSubtree (newNode, false); - prevNode = newNode; - } else { - prevNode = *it; - } - } -} - - - -bool -ConstraintTree::containsTuple (const Tuple& tuple) -{ - CTNode* prevNode = root_; - for (size_t i = 0; i < tuple.size(); i++) { - CTChilds::const_iterator it = prevNode->findSymbol (tuple[i]); - if (it == prevNode->childs().end()) { - return false; - } else { - prevNode = *it; - } - } - return true; -} - - - -void -ConstraintTree::moveToTop (const LogVars& lvs) -{ - for (size_t i = 0; i < lvs.size(); i++) { - size_t pos = Util::indexOf (logVars_, lvs[i]); - assert (pos != logVars_.size()); - for (size_t j = pos; j-- > i; ) { - swapLogVar (logVars_[j]); - } - } -} - - - -void -ConstraintTree::moveToBottom (const LogVars& lvs) -{ - for (size_t i = lvs.size(); i-- > 0; ) { - size_t pos = Util::indexOf (logVars_, lvs[i]); - assert (pos != logVars_.size()); - size_t stop = logVars_.size() - (lvs.size() - i - 1); - for (size_t j = pos; j < stop - 1; j++) { - swapLogVar (logVars_[j]); - } - } -} - - - -void -ConstraintTree::join (ConstraintTree* ct, bool oneTwoOne) -{ - if (logVarSet_.empty()) { - CTNode::deleteSubtree (root_); - root_ = CTNode::copySubtree (ct->root()); - logVars_ = ct->logVars(); - logVarSet_ = ct->logVarSet(); - return; - } - if (oneTwoOne) { - if (logVarSet_.contains (ct->logVarSet())) { - return; - } - if (ct->logVarSet().contains (logVarSet_)) { - CTNode::deleteSubtree (root_); - root_ = CTNode::copySubtree (ct->root()); - logVars_ = ct->logVars(); - logVarSet_ = ct->logVarSet(); - return; - } - } - LogVarSet intersect = logVarSet_ & ct->logVarSet_; - if (intersect.empty()) { - // cartesian product - appendOnBottom (root_, ct->root()->childs()); - Util::addToVector (logVars_, ct->logVars_); - logVarSet_ |= ct->logVarSet_; - } else { - moveToTop (intersect.elements()); - ct->moveToTop (intersect.elements()); - - Tuples tuples; - CTNodes appendNodes; - getTuples (ct->root(), Tuples(), intersect.size(), - tuples, appendNodes); - - CTNodes::const_iterator appendIt = appendNodes.begin(); - for (size_t i = 0; i < tuples.size(); ++ i, ++ appendIt) { - bool tupleFounded = join (root_, tuples[i], 0, *appendIt); - if (oneTwoOne && tupleFounded == false) { - assert (false); - } - } - - LogVars newLvs (ct->logVars().begin() + intersect.size(), - ct->logVars().end()); - Util::addToVector (logVars_, newLvs); - logVarSet_ |= LogVarSet (newLvs); - } -} - - - -unsigned -ConstraintTree::getLevel (LogVar X) const -{ - unsigned level = Util::indexOf (logVars_, X); - level += 1; // root is in level 0, first logVar is in level 1 - return level; -} - - - -void -ConstraintTree::rename (LogVar X_old, LogVar X_new) -{ - assert (logVarSet_.contains (X_old)); - assert (logVarSet_.contains (X_new) == false); - logVarSet_ -= X_old; - logVarSet_ |= X_new; - for (size_t i = 0; i < logVars_.size(); i++) { - if (logVars_[i] == X_old) { - logVars_[i] = X_new; - return; - } - } - assert (false); -} - - - -void -ConstraintTree::applySubstitution (const Substitution& theta) -{ - for (size_t i = 0; i < logVars_.size(); i++) { - logVars_[i] = theta.newNameFor (logVars_[i]); - } - logVarSet_ = LogVarSet (logVars_); -} - - - -void -ConstraintTree::project (const LogVarSet& X) -{ - assert (logVarSet_.contains (X)); - remove ((logVarSet_ - X)); -} - - - -ConstraintTree -ConstraintTree::projectedCopy (const LogVarSet& X) -{ - ConstraintTree copy = *this; - copy.project (X); - return copy; -} - - - -void -ConstraintTree::remove (const LogVarSet& X) -{ - assert (logVarSet_.contains (X)); - if (X.empty()) { - return; - } - moveToBottom (X.elements()); - unsigned level = getLevel (X.front()) - 1; - CTNodes nodes = getNodesAtLevel (level); - for (CTNodes::const_iterator it = nodes.begin(); - it != nodes.end(); ++ it) { - (*it)->removeAndDeleteAllChilds(); - } - logVars_.resize (logVars_.size() - X.size()); - logVarSet_ -= X; -} - - - -bool -ConstraintTree::ConstraintTree::isSingleton (LogVar X) -{ - Symbol symb; - unsigned level = getLevel (X); - CTNodes stack; - stack.push_back (root_); - while (stack.empty() == false) { - CTNode* node = stack.back(); - stack.pop_back(); - if (node->level() == level) { - if (symb.valid()) { - if (node->symbol() != symb) { - return false; - } - } else { - symb = node->symbol(); - } - } else { - stack.insert (stack.end(), node->childs().begin(), - node->childs().end()); - } - } - return true; -} - - - -LogVarSet -ConstraintTree::singletons (void) -{ - LogVarSet singletons; - for (size_t i = 0; i < logVars_.size(); i++) { - if (isSingleton (logVars_[i])) { - singletons.insert (logVars_[i]); - } - } - return singletons; -} - - - -TupleSet -ConstraintTree::tupleSet (unsigned stopLevel) const -{ - assert (root_->isRoot()); - Tuples tuples; - if (stopLevel == 0) { - stopLevel = logVars_.size(); - } - getTuples (root_, Tuples(), stopLevel, tuples, CTNodes() = {}); - return TupleSet (tuples); -} - - - -TupleSet -ConstraintTree::tupleSet (const LogVars& originalLvs) -{ - LogVars uniqueLvs; - for (size_t i = 0; i < originalLvs.size(); i++) { - if (Util::contains (uniqueLvs, originalLvs[i]) == false) { - uniqueLvs.push_back (originalLvs[i]); - } - } - - Tuples tuples; - moveToTop (uniqueLvs); - unsigned stopLevel = uniqueLvs.size(); - getTuples (root_, Tuples(), stopLevel, tuples, CTNodes() = {}); - - if (originalLvs.size() != uniqueLvs.size()) { - vector indexes; - indexes.reserve (originalLvs.size()); - for (size_t i = 0; i < originalLvs.size(); i++) { - indexes.push_back (Util::indexOf (uniqueLvs, originalLvs[i])); - } - Tuples tuples2; - tuples2.reserve (tuples.size()); - for (size_t i = 0; i < tuples.size(); i++) { - Tuple t; - t.reserve (originalLvs.size()); - for (size_t j = 0; j < originalLvs.size(); j++) { - t.push_back (tuples[i][indexes[j]]); - } - tuples2.push_back (t); - } - return TupleSet (tuples2); - } - - return TupleSet (tuples); -} - - - -void -ConstraintTree::exportToGraphViz ( - const char* fileName, - bool showLogVars) const -{ - ofstream out (fileName); - if (!out.is_open()) { - cerr << "Error: couldn't open file '" << fileName << "'." ; - return; - } - out << "digraph {" << endl; - ConstraintTree copy (*this); - copy.moveToTop (copy.logVarSet_.elements()); - CTNodes nodes = getNodesBelow (copy.root_); - out << "\"" << copy.root_ << "\"" << " [label=\"R\"]" << endl; - for (CTNodes::const_iterator it = ++ nodes.begin(); - it != nodes.end(); ++ it) { - out << "\"" << *it << "\""; - out << " [label=\"" << **it << "\"]" ; - out << endl; - } - for (CTNodes::const_iterator it = nodes.begin(); - it != nodes.end(); ++ it) { - const CTChilds& childs = (*it)->childs(); - for (CTChilds::const_iterator chIt = childs.begin(); - chIt != childs.end(); ++ chIt) { - out << "\"" << *it << "\"" ; - out << " -> " ; - out << "\"" << *chIt << "\"" << endl ; - } - } - if (showLogVars) { - out << "Root [label=\"\", shape=plaintext]" << endl; - for (size_t i = 0; i < copy.logVars_.size(); i++) { - out << copy.logVars_[i] << " [label=" ; - out << copy.logVars_[i] << ", " ; - out << "shape=plaintext, fontsize=14]" << endl; - } - out << "Root -> " << copy.logVars_[0]; - out << " [style=invis]" << endl; - for (size_t i = 0; i < copy.logVars_.size() - 1; i++) { - out << copy.logVars_[i] << " -> " << copy.logVars_[i + 1]; - out << " [style=invis]" << endl; - } - } - out << "}" << endl; - out.close(); -} - - - -bool -ConstraintTree::isCountNormalized (const LogVarSet& Ys) -{ - assert (logVarSet_.contains (Ys)); - if (Ys.empty()) { - return true; - } - if (Ys.size() == logVars_.size()) { - assert (LogVarSet (logVars_) == LogVarSet (Ys)); - return true; - } - LogVarSet Zs = logVarSet_ - LogVarSet (Ys); - moveToTop (Zs.elements()); - CTNodes nodes = getNodesAtLevel (Zs.size()); - unsigned count = countTuples (*nodes.begin()); - for (CTNodes::const_iterator it = nodes.begin(); - it != nodes.end(); ++ it) { - if (countTuples (*it) != count) { - return false; - } - } - return true; -} - - - -unsigned -ConstraintTree::getConditionalCount (const LogVarSet& Ys) -{ - assert (isCountNormalized (Ys)); - if (Ys.empty()) { - return 1; - } - if (Ys.size() == logVars_.size()) { - assert (LogVarSet (Ys) == LogVarSet (logVars_)); - return countTuples (root_); - } - LogVarSet Zs = logVarSet_ - Ys; - moveToTop (Zs.elements()); - CTNode* n = root_; - unsigned l = 0; - while (l != Zs.size()) { - n = *(n->childs().begin()); - l ++; - } - return countTuples (n); -} - - - -TinySet -ConstraintTree::getConditionalCounts (const LogVarSet& Ys) -{ - TinySet counts; - assert (logVarSet_.contains (Ys)); - if (Ys.empty()) { - counts.insert (1); - } else if (Ys.size() == logVars_.size()) { - assert (LogVarSet (logVars_) == LogVarSet (Ys)); - counts.insert (countTuples (root_)); - } else { - LogVarSet Zs = logVarSet_ - LogVarSet (Ys); - moveToTop (Zs.elements()); - CTNodes nodes = getNodesAtLevel (Zs.size()); - for (CTNodes::const_iterator it = nodes.begin(); - it != nodes.end(); ++ it) { - counts.insert (countTuples (*it)); - } - } - return counts; -} - - - -bool -ConstraintTree::isCartesianProduct (const LogVarSet& Xs) -{ - assert (logVarSet_.contains (Xs)); - if (Xs.size() <= 1) { - return true; - } - moveToTop (Xs.elements()); - for (size_t i = 1; i < Xs.size(); i++) { - CTNodes nodes = getNodesAtLevel (i); - for (size_t j = 1; j < nodes.size(); j++) { - if (nodes[j-1]->nrChilds() != nodes[ j ]->nrChilds()) { - return false; - } - if (nodes[j-1]->childSymbols() != nodes[ j ]->childSymbols()) { - return false; - } - } - } - return true; -} - - - -std::pair -ConstraintTree::split (const Tuple& tuple) -{ - // assumes that my log vars are already on top - LogVars lvs (logVars_.begin(), logVars_.begin() + tuple.size()); - ConstraintTree tempCt (logVars_, {tuple}); - return split (lvs, &tempCt, lvs); -} - - - -std::pair -ConstraintTree::split ( - const LogVars& lvs1, - ConstraintTree* ct, - const LogVars& lvs2) -{ - assert (lvs1.size() == lvs2.size()); - assert (lvs1.size() == LogVarSet (lvs1).size()); - assert (lvs2.size() == LogVarSet (lvs2).size()); - assert (logVarSet_.contains (lvs1)); - assert (ct->logVarSet().contains (lvs2)); - CTChilds commChilds, exclChilds; - unsigned stopLevel = lvs1.size(); - split (root_, ct->root(), commChilds, exclChilds, stopLevel); - ConstraintTree* commCt = new ConstraintTree (commChilds, logVars_); - ConstraintTree* exclCt = new ConstraintTree (exclChilds, logVars_); - // cout << commCt->tupleSet() << " + " ; - // cout << exclCt->tupleSet() << " = " ; - // cout << tupleSet() << endl; - assert ((commCt->tupleSet() | exclCt->tupleSet()) == tupleSet()); - assert ((exclCt->tupleSet (stopLevel) & ct->tupleSet (stopLevel)).empty()); - return {commCt, exclCt}; -} - - - -ConstraintTrees -ConstraintTree::countNormalize (const LogVarSet& Ys) -{ - assert (logVarSet_.contains (Ys)); - LogVarSet Zs = logVarSet_ - Ys; - if (Ys.empty() || Zs.empty()) { - return { new ConstraintTree (*this) }; - } - moveToTop (Zs.elements()); - ConstraintTrees cts; - unordered_map countMap; - unsigned stopLevel = getLevel (Zs.back()); - const CTChilds& childs = root_->childs(); - - for (CTChilds::const_iterator chIt = childs.begin(); - chIt != childs.end(); ++ chIt) { - const vector>& res = - countNormalize (*chIt, stopLevel); - for (size_t j = 0; j < res.size(); j++) { - unordered_map::iterator it - = countMap.find (res[j].second); - if (it == countMap.end()) { - ConstraintTree* newCt = new ConstraintTree (logVars_); - it = countMap.insert (make_pair (res[j].second, newCt)).first; - cts.push_back (newCt); - } - it->second->root_->mergeSubtree (res[j].first); - } - } - return cts; -} - - - -ConstraintTrees -ConstraintTree::jointCountNormalize ( - ConstraintTree* commCt, - ConstraintTree* exclCt, - LogVar X, - LogVar X_new1, - LogVar X_new2) -{ - unsigned N = getConditionalCount (X); - // cout << "My tuples: " << tupleSet() << endl; - // cout << "CommCt tuples: " << commCt->tupleSet() << endl; - // cout << "ExclCt tuples: " << exclCt->tupleSet() << endl; - // cout << "Counted Lv: " << X << endl; - // cout << "X_new1: " << X_new1 << endl; - // cout << "X_new2: " << X_new2 << endl; - // cout << "Original N: " << N << endl; - // cout << endl; - - ConstraintTrees normCts1 = commCt->countNormalize (X); - vector counts1 (normCts1.size()); - for (size_t i = 0; i < normCts1.size(); i++) { - counts1[i] = normCts1[i]->getConditionalCount (X); - // cout << "normCts1[" << i << "] #" << counts1[i] ; - // cout << " " << normCts1[i]->tupleSet() << endl; - } - - ConstraintTrees normCts2 = exclCt->countNormalize (X); - vector counts2 (normCts2.size()); - for (size_t i = 0; i < normCts2.size(); i++) { - counts2[i] = normCts2[i]->getConditionalCount (X); - // cout << "normCts2[" << i << "] #" << counts2[i] ; - // cout << " " << normCts2[i]->tupleSet() << endl; - } - // cout << endl; - - ConstraintTree* excl1 = 0; - for (size_t i = 0; i < normCts1.size(); i++) { - if (counts1[i] == N) { - excl1 = normCts1[i]; - normCts1.erase (normCts1.begin() + i); - counts1.erase (counts1.begin() + i); - // cout << "joint-count(" << N << ",0)" << endl; - break; - } - } - - ConstraintTree* excl2 = 0; - for (size_t i = 0; i < normCts2.size(); i++) { - if (counts2[i] == N) { - excl2 = normCts2[i]; - normCts2.erase (normCts2.begin() + i); - counts2.erase (counts2.begin() + i); - // cout << "joint-count(0," << N << ")" << endl; - break; - } - } - - for (size_t i = 0; i < normCts1.size(); i++) { - unsigned j; - for (j = 0; counts1[i] + counts2[j] != N; j++) ; - // cout << "joint-count(" << counts1[i] ; - // cout << "," << counts2[j] << ")" << endl; - const CTChilds& childs = normCts2[j]->root_->childs(); - for (CTChilds::const_iterator chIt = childs.begin(); - chIt != childs.end(); ++ chIt) { - normCts1[i]->root_->mergeSubtree (CTNode::copySubtree (*chIt)); - } - delete normCts2[j]; - } - - ConstraintTrees cts = normCts1; - commCt->rename (X, X_new1); - exclCt->rename (X, X_new2); - for (size_t i = 0; i < cts.size(); i++) { - cts[i]->remove (X); - cts[i]->join (commCt); - cts[i]->join (exclCt); - } - - if (excl1 != 0) { - cts.push_back (excl1); - } - if (excl2 != 0) { - cts.push_back (excl2); - } - - return cts; -} - - - -LogVars -ConstraintTree::expand (LogVar X) -{ - moveToBottom ({X}); - assert (isCountNormalized (X)); - CTNodes nodes = getNodesAtLevel (logVars_.size() - 1); - unsigned nrSymbols = getConditionalCount (X); - for (CTNodes::const_iterator it = nodes.begin(); - it != nodes.end(); ++ it) { - Symbols symbols; - const CTChilds& childs = (*it)->childs(); - for (CTChilds::const_iterator chIt = childs.begin(); - chIt != childs.end(); ++ chIt) { - symbols.push_back ((*chIt)->symbol()); - } - (*it)->removeAndDeleteAllChilds(); - CTNode* prev = *it; - assert (symbols.size() == nrSymbols); - for (size_t j = 0; j < nrSymbols; j++) { - CTNode* newNode = new CTNode (symbols[j], (*it)->level() + j); - prev->mergeSubtree (newNode); - prev = newNode; - } - } - LogVars newLvs; - logVars_.pop_back(); - for (size_t i = 0; i < nrSymbols; i++) { - logVars_.push_back (LogVar (logVarSet_.back() + 1)); - newLvs.push_back (LogVar (logVarSet_.back() + 1)); - logVarSet_.insert (LogVar (logVarSet_.back() + 1)); - } - logVarSet_ -= X; - return newLvs; -} - - - -ConstraintTrees -ConstraintTree::ground (LogVar X) -{ - moveToTop ({X}); - ConstraintTrees cts; - const CTChilds& nodes = root_->childs(); - for (CTChilds::const_iterator it = nodes.begin(); - it != nodes.end(); ++ it) { - CTNode* copy = CTNode::copySubtree (*it); - copy->setSymbol ((*it)->symbol()); - ConstraintTree* newCt = new ConstraintTree (logVars_); - newCt->root()->mergeSubtree (copy); - cts.push_back (newCt); - } - return cts; -} - - - -void -ConstraintTree::cloneLogVar (LogVar X_1, LogVar X_2) -{ - moveToBottom ({X_1}); - CTNodes leafs = getNodesAtLevel (logVars_.size()); - for (size_t i = 0; i < leafs.size(); i++) { - leafs[i]->childs().insert_sorted ( - new CTNode (leafs[i]->symbol(), leafs[i]->level() + 1)); - } - logVars_.push_back (X_2); - logVarSet_.insert (X_2); -} - - - -ConstraintTree& -ConstraintTree::operator= (const ConstraintTree& ct) -{ - if (this != &ct) { - root_ = CTNode::copySubtree (ct.root_); - logVars_ = ct.logVars_; - logVarSet_ = ct.logVarSet_; - } - return *this; -} - - - -unsigned -ConstraintTree::countTuples (const CTNode* n) const -{ - if (n->isLeaf()) { - return 1; - } - unsigned sum = 0; - const CTChilds& childs = n->childs(); - for (CTChilds::const_iterator chIt = childs.begin(); - chIt != childs.end(); ++ chIt) { - sum += countTuples (*chIt); - } - return sum; -} - - - -CTNodes -ConstraintTree::getNodesBelow (CTNode* fromHere) const -{ - CTNodes nodes; - queue queue; - queue.push (fromHere); - while (queue.empty() == false) { - CTNode* node = queue.front(); - nodes.push_back (node); - for (CTChilds::const_iterator chIt = node->childs().begin(); - chIt != node->childs().end(); ++ chIt) { - queue.push (*chIt); - } - queue.pop(); - } - return nodes; -} - - - -CTNodes -ConstraintTree::getNodesAtLevel (unsigned level) const -{ - assert (level <= logVars_.size()); - if (level == 0) { - return { root_ }; - } - CTNodes stack; - CTNodes nodes; - stack.push_back (root_); - while (stack.empty() == false) { - CTNode* node = stack.back(); - stack.pop_back(); - if (node->level() + 1 == level) { - nodes.insert (nodes.end(), node->childs().begin(), - node->childs().end()); - } else { - stack.insert (stack.end(), node->childs().begin(), - node->childs().end()); - } - } - return nodes; -} - - - -unsigned -ConstraintTree::nrNodes (const CTNode* n) const -{ - unsigned nr = 0; - if (n->isLeaf() == false) { - for (CTChilds::const_iterator chIt = n->childs().begin(); - chIt != n->childs().end(); ++ chIt) { - nr += nrNodes (*chIt); - } - } - return nr; -} - - - -void -ConstraintTree::appendOnBottom (CTNode* n, const CTChilds& childs) -{ - if (childs.empty()) { - return; - } - CTNodes stack { n }; - while (stack.empty() == false) { - CTNode* node = stack.back(); - stack.pop_back(); - if (node->isLeaf()) { - for (CTChilds::const_iterator chIt = childs.begin(); - chIt != childs.end(); ++ chIt) { - node->mergeSubtree (CTNode::copySubtree (*chIt)); - } - } else { - stack.insert (stack.end(), node->childs().begin(), - node->childs().end()); - } - } -} - - - -void -ConstraintTree::swapLogVar (LogVar X) -{ - size_t pos = Util::indexOf (logVars_, X); - assert (pos != logVars_.size()); - const CTNodes& nodes = getNodesAtLevel (pos); - for (CTNodes::const_iterator nodeIt = nodes.begin(); - nodeIt != nodes.end(); ++ nodeIt) { - CTChilds childsCopy = (*nodeIt)->childs(); - (*nodeIt)->removeChilds(); - for (CTChilds::const_iterator ccIt = childsCopy.begin(); - ccIt != childsCopy.end(); ++ ccIt) { - const CTChilds& grandsons = (*ccIt)->childs(); - for (CTChilds::const_iterator gsIt = grandsons.begin(); - gsIt != grandsons.end(); ++ gsIt) { - CTNode* childCopy = new CTNode ( - (*ccIt)->symbol(), (*ccIt)->level() + 1, (*gsIt)->childs()); - (*gsIt)->removeChilds(); - (*gsIt)->childs().insert_sorted (childCopy); - (*gsIt)->setLevel ((*gsIt)->level() - 1); - (*nodeIt)->mergeSubtree ((*gsIt), false); - } - delete (*ccIt); - } - } - std::swap (logVars_[pos], logVars_[pos + 1]); -} - - - -bool -ConstraintTree::join ( - CTNode* currNode, - const Tuple& tuple, - size_t currIdx, - CTNode* appendNode) -{ - bool tupleFounded = false; - CTChilds::const_iterator it = currNode->findSymbol (tuple[currIdx]); - if (it != currNode->childs().end()) { - if (currIdx == tuple.size() - 1) { - appendOnBottom (*it, appendNode->childs()); - return true; - } else { - tupleFounded = join (*it, tuple, currIdx + 1, appendNode); - } - } - return tupleFounded; -} - - - -void -ConstraintTree::getTuples ( - CTNode* n, - Tuples currTuples, - unsigned stopLevel, - Tuples& tuplesCollected, - CTNodes& continuationNodes) const -{ - if (n->isRoot() == false) { - if (currTuples.size() == 0) { - currTuples.push_back ({ n->symbol()}); - } else { - for (size_t i = 0; i < currTuples.size(); i++) { - currTuples[i].push_back (n->symbol()); - } - } - if (n->level() == stopLevel) { - for (size_t i = 0; i < currTuples.size(); i++) { - tuplesCollected.push_back (currTuples[i]); - continuationNodes.push_back (n); - } - return; - } - } - const CTChilds& childs = n->childs(); - for (CTChilds::const_iterator chIt = childs.begin(); - chIt != childs.end(); ++ chIt) { - getTuples (*chIt, currTuples, stopLevel, tuplesCollected, - continuationNodes); - } -} - - - -unsigned -ConstraintTree::size (void) const -{ - return countTuples (root_); -} - - - -unsigned -ConstraintTree::nrSymbols (LogVar X) -{ - moveToTop ({X}); - return root_->childs().size(); -} - - - -vector> -ConstraintTree::countNormalize ( - const CTNode* n, - unsigned stopLevel) -{ - if (n->level() == stopLevel) { - return vector>() = { - make_pair (CTNode::copySubtree (n), countTuples (n)) - }; - } - vector> res; - const CTChilds& childs = n->childs(); - for (CTChilds::const_iterator chIt = childs.begin(); - chIt != childs.end(); ++ chIt) { - const vector>& lowerRes = - countNormalize (*chIt, stopLevel); - for (size_t j = 0; j < lowerRes.size(); j++) { - CTNode* newNode = new CTNode (*n); - newNode->mergeSubtree (lowerRes[j].first); - res.push_back (make_pair (newNode, lowerRes[j].second)); - } - } - return res; -} - - - -void -ConstraintTree::split ( - CTNode* n1, - CTNode* n2, - CTChilds& commChilds, - CTChilds& exclChilds, - unsigned stopLevel) -{ - CTChilds& childs1 = n1->childs(); - for (CTChilds::const_iterator chIt1 = childs1.begin(); - chIt1 != childs1.end(); ++ chIt1) { - CTChilds::iterator chIt2 = n2->findSymbol ((*chIt1)->symbol()); - if (chIt2 == n2->childs().end()) { - exclChilds.insert_sorted (CTNode::copySubtree (*chIt1)); - } else { - if ((*chIt1)->level() == stopLevel) { - commChilds.insert_sorted (CTNode::copySubtree (*chIt1)); - } else { - CTChilds lowerCommChilds, lowerExclChilds; - split (*chIt1, *chIt2, lowerCommChilds, lowerExclChilds, stopLevel); - if (lowerCommChilds.empty() == false) { - commChilds.insert_sorted (new CTNode (**chIt1, lowerCommChilds)); - } - if (lowerExclChilds.empty() == false) { - exclChilds.insert_sorted (new CTNode (**chIt1, lowerExclChilds)); - } - } - } - } -} - diff --git a/packages/CLPBN/horus2/ConstraintTree.h b/packages/CLPBN/horus2/ConstraintTree.h deleted file mode 100644 index cccb070b4..000000000 --- a/packages/CLPBN/horus2/ConstraintTree.h +++ /dev/null @@ -1,237 +0,0 @@ -#ifndef HORUS_CONSTRAINTTREE_H -#define HORUS_CONSTRAINTTREE_H - -#include -#include - -#include -#include - -#include "TinySet.h" -#include "LiftedUtils.h" - -using namespace std; - - -class CTNode; -typedef vector CTNodes; - -class ConstraintTree; -typedef vector ConstraintTrees; - - -class CTNode -{ - public: - - struct CompareSymbol - { - bool operator() (const CTNode* n1, const CTNode* n2) const - { - return n1->symbol() < n2->symbol(); - } - }; - - private: - - typedef TinySet CTChilds_; - - public: - - CTNode (const CTNode& n, const CTChilds_& chs = CTChilds_()) - : symbol_(n.symbol()), childs_(chs), level_(n.level()) { } - - CTNode (Symbol s, unsigned l, const CTChilds_& chs = CTChilds_()) - : symbol_(s), childs_(chs), level_(l) { } - - unsigned level (void) const { return level_; } - - void setLevel (unsigned level) { level_ = level; } - - Symbol symbol (void) const { return symbol_; } - - void setSymbol (const Symbol s) { symbol_ = s; } - - public: - - CTChilds_& childs (void) { return childs_; } - - const CTChilds_& childs (void) const { return childs_; } - - size_t nrChilds (void) const { return childs_.size(); } - - bool isRoot (void) const { return level_ == 0; } - - bool isLeaf (void) const { return childs_.empty(); } - - CTChilds_::iterator findSymbol (Symbol symb) - { - CTNode tmp (symb, 0); - return childs_.find (&tmp); - } - - void mergeSubtree (CTNode*, bool = true); - - void removeChild (CTNode*); - - void removeChilds (void); - - void removeAndDeleteChild (CTNode*); - - void removeAndDeleteAllChilds (void); - - SymbolSet childSymbols (void) const; - - static CTNode* copySubtree (const CTNode*); - - static void deleteSubtree (CTNode*); - - private: - void updateChildLevels (CTNode*, unsigned); - - Symbol symbol_; - CTChilds_ childs_; - unsigned level_; -}; - -ostream& operator<< (ostream &out, const CTNode&); - - -typedef TinySet CTChilds; - - -class ConstraintTree -{ - public: - ConstraintTree (unsigned); - - ConstraintTree (const LogVars&); - - ConstraintTree (const LogVars&, const Tuples&); - - ConstraintTree (vector> names); - - ConstraintTree (const ConstraintTree&); - - ConstraintTree (const CTChilds& rootChilds, const LogVars& logVars) - : root_(new CTNode (0, 0, rootChilds)), - logVars_(logVars), - logVarSet_(logVars) { } - - ~ConstraintTree (void); - - CTNode* root (void) const { return root_; } - - bool empty (void) const { return root_->childs().empty(); } - - const LogVars& logVars (void) const - { - assert (LogVarSet (logVars_) == logVarSet_); - return logVars_; - } - - const LogVarSet& logVarSet (void) const - { - assert (LogVarSet (logVars_) == logVarSet_); - return logVarSet_; - } - - size_t nrLogVars (void) const - { - return logVars_.size(); - assert (LogVarSet (logVars_) == logVarSet_); - } - - void addTuple (const Tuple&); - - bool containsTuple (const Tuple&); - - void moveToTop (const LogVars&); - - void moveToBottom (const LogVars&); - - void join (ConstraintTree*, bool oneTwoOne = false); - - unsigned getLevel (LogVar) const; - - void rename (LogVar, LogVar); - - void applySubstitution (const Substitution&); - - void project (const LogVarSet&); - - ConstraintTree projectedCopy (const LogVarSet&); - - void remove (const LogVarSet&); - - bool isSingleton (LogVar); - - LogVarSet singletons (void); - - TupleSet tupleSet (unsigned = 0) const; - - TupleSet tupleSet (const LogVars&); - - unsigned size (void) const; - - unsigned nrSymbols (LogVar); - - void exportToGraphViz (const char*, bool = false) const; - - bool isCountNormalized (const LogVarSet&); - - unsigned getConditionalCount (const LogVarSet&); - - TinySet getConditionalCounts (const LogVarSet&); - - bool isCartesianProduct (const LogVarSet&); - - std::pair split (const Tuple&); - - std::pair split ( - const LogVars&, ConstraintTree*, const LogVars&); - - ConstraintTrees countNormalize (const LogVarSet&); - - ConstraintTrees jointCountNormalize ( - ConstraintTree*, ConstraintTree*, LogVar, LogVar, LogVar); - - LogVars expand (LogVar); - - ConstraintTrees ground (LogVar); - - void cloneLogVar (LogVar, LogVar); - - ConstraintTree& operator= (const ConstraintTree& ct); - - private: - unsigned countTuples (const CTNode*) const; - - CTNodes getNodesBelow (CTNode*) const; - - CTNodes getNodesAtLevel (unsigned) const; - - unsigned nrNodes (const CTNode* n) const; - - void appendOnBottom (CTNode* n1, const CTChilds&); - - void swapLogVar (LogVar); - - bool join (CTNode*, const Tuple&, size_t, CTNode*); - - void getTuples (CTNode*, Tuples, unsigned, Tuples&, CTNodes&) const; - - vector> countNormalize ( - const CTNode*, unsigned); - - static void split ( - CTNode*, CTNode*, CTChilds&, CTChilds&, unsigned); - - CTNode* root_; - LogVars logVars_; - LogVarSet logVarSet_; -}; - - -#endif // HORUS_CONSTRAINTTREE_H - diff --git a/packages/CLPBN/horus2/CountingBp.cpp b/packages/CLPBN/horus2/CountingBp.cpp deleted file mode 100644 index d248c602c..000000000 --- a/packages/CLPBN/horus2/CountingBp.cpp +++ /dev/null @@ -1,424 +0,0 @@ -#include "CountingBp.h" -#include "WeightedBp.h" - - -bool CountingBp::checkForIdenticalFactors = true; - - -CountingBp::CountingBp (const FactorGraph& fg) - : GroundSolver (fg), freeColor_(0) -{ - findIdenticalFactors(); - setInitialColors(); - createGroups(); - compressedFg_ = getCompressedFactorGraph(); - solver_ = new WeightedBp (*compressedFg_, getWeights()); -} - - - -CountingBp::~CountingBp (void) -{ - delete solver_; - delete compressedFg_; - for (size_t i = 0; i < varClusters_.size(); i++) { - delete varClusters_[i]; - } - for (size_t i = 0; i < facClusters_.size(); i++) { - delete facClusters_[i]; - } -} - - - -void -CountingBp::printSolverFlags (void) const -{ - stringstream ss; - ss << "counting bp [" ; - ss << "schedule=" ; - typedef BpOptions::Schedule Sch; - switch (BpOptions::schedule) { - case Sch::SEQ_FIXED: ss << "seq_fixed"; break; - case Sch::SEQ_RANDOM: ss << "seq_random"; break; - case Sch::PARALLEL: ss << "parallel"; break; - case Sch::MAX_RESIDUAL: ss << "max_residual"; break; - } - ss << ",max_iter=" << BpOptions::maxIter; - ss << ",accuracy=" << BpOptions::accuracy; - ss << ",log_domain=" << Util::toString (Globals::logDomain); - ss << ",chkif=" << - Util::toString (CountingBp::checkForIdenticalFactors); - ss << "]" ; - cout << ss.str() << endl; -} - - - -Params -CountingBp::solveQuery (VarIds queryVids) -{ - assert (queryVids.empty() == false); - Params res; - if (queryVids.size() == 1) { - res = solver_->getPosterioriOf (getRepresentative (queryVids[0])); - } else { - VarNode* vn = fg.getVarNode (queryVids[0]); - const FacNodes& facNodes = vn->neighbors(); - size_t idx = facNodes.size(); - for (size_t i = 0; i < facNodes.size(); i++) { - if (facNodes[i]->factor().contains (queryVids)) { - idx = i; - break; - } - cout << endl; - } - if (idx == facNodes.size()) { - res = GroundSolver::getJointByConditioning ( - GroundSolverType::CBP, fg, queryVids); - } else { - VarIds reprArgs; - for (size_t i = 0; i < queryVids.size(); i++) { - reprArgs.push_back (getRepresentative (queryVids[i])); - } - FacNode* reprFac = getRepresentative (facNodes[idx]); - assert (reprFac != 0); - res = solver_->getFactorJoint (reprFac, reprArgs); - } - } - return res; -} - - - -void -CountingBp::findIdenticalFactors() -{ - const FacNodes& facNodes = fg.facNodes(); - if (checkForIdenticalFactors == false || - facNodes.size() == 1) { - return; - } - for (size_t i = 0; i < facNodes.size(); i++) { - facNodes[i]->factor().setDistId (Util::maxUnsigned()); - } - unsigned groupCount = 1; - for (size_t i = 0; i < facNodes.size() - 1; i++) { - Factor& f1 = facNodes[i]->factor(); - if (f1.distId() != Util::maxUnsigned()) { - continue; - } - f1.setDistId (groupCount); - for (size_t j = i + 1; j < facNodes.size(); j++) { - Factor& f2 = facNodes[j]->factor(); - if (f2.distId() != Util::maxUnsigned()) { - continue; - } - if (f1.size() == f2.size() && - f1.ranges() == f2.ranges() && - f1.params() == f2.params()) { - f2.setDistId (groupCount); - } - } - groupCount ++; - } -} - - - -void -CountingBp::setInitialColors (void) -{ - varColors_.resize (fg.nrVarNodes()); - facColors_.resize (fg.nrFacNodes()); - // create the initial variable colors - VarColorMap colorMap; - const VarNodes& varNodes = fg.varNodes(); - for (size_t i = 0; i < varNodes.size(); i++) { - unsigned range = varNodes[i]->range(); - VarColorMap::iterator it = colorMap.find (range); - if (it == colorMap.end()) { - it = colorMap.insert (make_pair ( - range, Colors (range + 1, -1))).first; - } - unsigned idx = varNodes[i]->hasEvidence() - ? varNodes[i]->getEvidence() - : range; - Colors& stateColors = it->second; - if (stateColors[idx] == -1) { - stateColors[idx] = getNewColor(); - } - setColor (varNodes[i], stateColors[idx]); - } - const FacNodes& facNodes = fg.facNodes(); - // create the initial factor colors - DistColorMap distColors; - for (size_t i = 0; i < facNodes.size(); i++) { - unsigned distId = facNodes[i]->factor().distId(); - DistColorMap::iterator it = distColors.find (distId); - if (it == distColors.end()) { - it = distColors.insert (make_pair (distId, getNewColor())).first; - } - setColor (facNodes[i], it->second); - } -} - - - -void -CountingBp::createGroups (void) -{ - VarSignMap varGroups; - FacSignMap facGroups; - unsigned nIters = 0; - bool groupsHaveChanged = true; - const VarNodes& varNodes = fg.varNodes(); - const FacNodes& facNodes = fg.facNodes(); - - while (groupsHaveChanged || nIters == 1) { - nIters ++; - - // set a new color to the variables with the same signature - size_t prevVarGroupsSize = varGroups.size(); - varGroups.clear(); - for (size_t i = 0; i < varNodes.size(); i++) { - const VarSignature& signature = getSignature (varNodes[i]); - VarSignMap::iterator it = varGroups.find (signature); - if (it == varGroups.end()) { - it = varGroups.insert (make_pair (signature, VarNodes())).first; - } - it->second.push_back (varNodes[i]); - } - for (VarSignMap::iterator it = varGroups.begin(); - it != varGroups.end(); ++it) { - Color newColor = getNewColor(); - VarNodes& groupMembers = it->second; - for (size_t i = 0; i < groupMembers.size(); i++) { - setColor (groupMembers[i], newColor); - } - } - - size_t prevFactorGroupsSize = facGroups.size(); - facGroups.clear(); - // set a new color to the factors with the same signature - for (size_t i = 0; i < facNodes.size(); i++) { - const FacSignature& signature = getSignature (facNodes[i]); - FacSignMap::iterator it = facGroups.find (signature); - if (it == facGroups.end()) { - it = facGroups.insert (make_pair (signature, FacNodes())).first; - } - it->second.push_back (facNodes[i]); - } - for (FacSignMap::iterator it = facGroups.begin(); - it != facGroups.end(); ++it) { - Color newColor = getNewColor(); - FacNodes& groupMembers = it->second; - for (size_t i = 0; i < groupMembers.size(); i++) { - setColor (groupMembers[i], newColor); - } - } - - groupsHaveChanged = prevVarGroupsSize != varGroups.size() - || prevFactorGroupsSize != facGroups.size(); - } - // printGroups (varGroups, facGroups); - createClusters (varGroups, facGroups); -} - - - -void -CountingBp::createClusters ( - const VarSignMap& varGroups, - const FacSignMap& facGroups) -{ - varClusters_.reserve (varGroups.size()); - for (VarSignMap::const_iterator it = varGroups.begin(); - it != varGroups.end(); ++it) { - const VarNodes& groupVars = it->second; - VarCluster* vc = new VarCluster (groupVars); - for (size_t i = 0; i < groupVars.size(); i++) { - varClusterMap_.insert (make_pair (groupVars[i]->varId(), vc)); - } - varClusters_.push_back (vc); - } - - facClusters_.reserve (facGroups.size()); - for (FacSignMap::const_iterator it = facGroups.begin(); - it != facGroups.end(); ++it) { - FacNode* groupFactor = it->second[0]; - const VarNodes& neighs = groupFactor->neighbors(); - VarClusters varClusters; - varClusters.reserve (neighs.size()); - for (size_t i = 0; i < neighs.size(); i++) { - VarId vid = neighs[i]->varId(); - varClusters.push_back (varClusterMap_.find (vid)->second); - } - facClusters_.push_back (new FacCluster (it->second, varClusters)); - } -} - - - -VarSignature -CountingBp::getSignature (const VarNode* varNode) -{ - const FacNodes& neighs = varNode->neighbors(); - VarSignature sign; - sign.reserve (neighs.size() + 1); - for (size_t i = 0; i < neighs.size(); i++) { - sign.push_back (make_pair ( - getColor (neighs[i]), - neighs[i]->factor().indexOf (varNode->varId()))); - } - std::sort (sign.begin(), sign.end()); - sign.push_back (make_pair (getColor (varNode), 0)); - return sign; -} - - - -FacSignature -CountingBp::getSignature (const FacNode* facNode) -{ - const VarNodes& neighs = facNode->neighbors(); - FacSignature sign; - sign.reserve (neighs.size() + 1); - for (size_t i = 0; i < neighs.size(); i++) { - sign.push_back (getColor (neighs[i])); - } - sign.push_back (getColor (facNode)); - return sign; -} - - - -VarId -CountingBp::getRepresentative (VarId vid) -{ - assert (Util::contains (varClusterMap_, vid)); - VarCluster* vc = varClusterMap_.find (vid)->second; - return vc->representative()->varId(); -} - - - -FacNode* -CountingBp::getRepresentative (FacNode* fn) -{ - for (size_t i = 0; i < facClusters_.size(); i++) { - if (Util::contains (facClusters_[i]->members(), fn)) { - return facClusters_[i]->representative(); - } - } - return 0; -} - - - -FactorGraph* -CountingBp::getCompressedFactorGraph (void) -{ - FactorGraph* fg = new FactorGraph(); - for (size_t i = 0; i < varClusters_.size(); i++) { - VarNode* newVar = new VarNode (varClusters_[i]->first()); - varClusters_[i]->setRepresentative (newVar); - fg->addVarNode (newVar); - } - for (size_t i = 0; i < facClusters_.size(); i++) { - Vars vars; - const VarClusters& clusters = facClusters_[i]->varClusters(); - for (size_t j = 0; j < clusters.size(); j++) { - vars.push_back (clusters[j]->representative()); - } - const Factor& groundFac = facClusters_[i]->first()->factor(); - FacNode* fn = new FacNode (Factor ( - vars, groundFac.params(), groundFac.distId())); - facClusters_[i]->setRepresentative (fn); - fg->addFacNode (fn); - for (size_t j = 0; j < vars.size(); j++) { - fg->addEdge (static_cast (vars[j]), fn); - } - } - return fg; -} - - - -vector> -CountingBp::getWeights (void) const -{ - vector> weights; - weights.reserve (facClusters_.size()); - for (size_t i = 0; i < facClusters_.size(); i++) { - const VarClusters& neighs = facClusters_[i]->varClusters(); - weights.push_back ({ }); - weights.back().reserve (neighs.size()); - for (size_t j = 0; j < neighs.size(); j++) { - weights.back().push_back (getWeight ( - facClusters_[i], neighs[j], j)); - } - } - return weights; -} - - - -unsigned -CountingBp::getWeight ( - const FacCluster* fc, - const VarCluster* vc, - size_t index) const -{ - unsigned weight = 0; - VarId reprVid = vc->representative()->varId(); - VarNode* groundVar = fg.getVarNode (reprVid); - const FacNodes& neighs = groundVar->neighbors(); - for (size_t i = 0; i < neighs.size(); i++) { - FacNodes::const_iterator it; - it = std::find (fc->members().begin(), fc->members().end(), neighs[i]); - if (it != fc->members().end() && - (*it)->factor().indexOf (reprVid) == index) { - weight ++; - } - } - return weight; -} - - - -void -CountingBp::printGroups ( - const VarSignMap& varGroups, - const FacSignMap& facGroups) const -{ - unsigned count = 1; - cout << "variable groups:" << endl; - for (VarSignMap::const_iterator it = varGroups.begin(); - it != varGroups.end(); ++it) { - const VarNodes& groupMembers = it->second; - if (groupMembers.size() > 0) { - cout << count << ": " ; - for (size_t i = 0; i < groupMembers.size(); i++) { - cout << groupMembers[i]->label() << " " ; - } - count ++; - cout << endl; - } - } - count = 1; - cout << endl << "factor groups:" << endl; - for (FacSignMap::const_iterator it = facGroups.begin(); - it != facGroups.end(); ++it) { - const FacNodes& groupMembers = it->second; - if (groupMembers.size() > 0) { - cout << ++count << ": " ; - for (size_t i = 0; i < groupMembers.size(); i++) { - cout << groupMembers[i]->getLabel() << " " ; - } - count ++; - cout << endl; - } - } -} - diff --git a/packages/CLPBN/horus2/CountingBp.h b/packages/CLPBN/horus2/CountingBp.h deleted file mode 100644 index 2cbd2f995..000000000 --- a/packages/CLPBN/horus2/CountingBp.h +++ /dev/null @@ -1,182 +0,0 @@ -#ifndef HORUS_COUNTINGBP_H -#define HORUS_COUNTINGBP_H - -#include - -#include "GroundSolver.h" -#include "FactorGraph.h" -#include "Util.h" -#include "Horus.h" - -class VarCluster; -class FacCluster; -class WeightedBp; - -typedef long Color; -typedef vector Colors; -typedef vector> VarSignature; -typedef vector FacSignature; - -typedef unordered_map DistColorMap; -typedef unordered_map VarColorMap; - -typedef unordered_map VarSignMap; -typedef unordered_map FacSignMap; - -typedef unordered_map VarClusterMap; - -typedef vector VarClusters; -typedef vector FacClusters; - -template -inline size_t hash_combine (size_t seed, const T& v) -{ - return seed ^ (hash()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2)); -} - - -namespace std { - template struct hash> - { - size_t operator() (const std::pair& p) const - { - return hash_combine (std::hash()(p.first), p.second); - } - }; - - template struct hash> - { - size_t operator() (const std::vector& vec) const - { - size_t h = 0; - typename vector::const_iterator first = vec.begin(); - typename vector::const_iterator last = vec.end(); - for (; first != last; ++first) { - h = hash_combine (h, *first); - } - return h; - } - }; -} - - -class VarCluster -{ - public: - VarCluster (const VarNodes& vs) : members_(vs) { } - - const VarNode* first (void) const { return members_.front(); } - - const VarNodes& members (void) const { return members_; } - - VarNode* representative (void) const { return repr_; } - - void setRepresentative (VarNode* vn) { repr_ = vn; } - - private: - VarNodes members_; - VarNode* repr_; -}; - - -class FacCluster -{ - public: - FacCluster (const FacNodes& fcs, const VarClusters& vcs) - : members_(fcs), varClusters_(vcs) { } - - const FacNode* first (void) const { return members_.front(); } - - const FacNodes& members (void) const { return members_; } - - FacNode* representative (void) const { return repr_; } - - void setRepresentative (FacNode* fn) { repr_ = fn; } - - VarClusters& varClusters (void) { return varClusters_; } - - private: - FacNodes members_; - FacNode* repr_; - VarClusters varClusters_; -}; - - -class CountingBp : public GroundSolver -{ - public: - CountingBp (const FactorGraph& fg); - - ~CountingBp (void); - - void printSolverFlags (void) const; - - Params solveQuery (VarIds); - - static bool checkForIdenticalFactors; - - private: - Color getNewColor (void) - { - ++ freeColor_; - return freeColor_ - 1; - } - - Color getColor (const VarNode* vn) const - { - return varColors_[vn->getIndex()]; - } - - Color getColor (const FacNode* fn) const - { - return facColors_[fn->getIndex()]; - } - - void setColor (const VarNode* vn, Color c) - { - varColors_[vn->getIndex()] = c; - } - - void setColor (const FacNode* fn, Color c) - { - facColors_[fn->getIndex()] = c; - } - - void findIdenticalFactors (void); - - void setInitialColors (void); - - void createGroups (void); - - void createClusters (const VarSignMap&, const FacSignMap&); - - VarSignature getSignature (const VarNode*); - - FacSignature getSignature (const FacNode*); - - void printGroups (const VarSignMap&, const FacSignMap&) const; - - VarId getRepresentative (VarId vid); - - FacNode* getRepresentative (FacNode*); - - FactorGraph* getCompressedFactorGraph (void); - - vector> getWeights (void) const; - - unsigned getWeight (const FacCluster*, - const VarCluster*, size_t index) const; - - - Color freeColor_; - Colors varColors_; - Colors facColors_; - VarClusters varClusters_; - FacClusters facClusters_; - VarClusterMap varClusterMap_; - const FactorGraph* compressedFg_; - WeightedBp* solver_; -}; - -#endif // HORUS_COUNTINGBP_H - diff --git a/packages/CLPBN/horus2/ElimGraph.cpp b/packages/CLPBN/horus2/ElimGraph.cpp deleted file mode 100644 index f617d8237..000000000 --- a/packages/CLPBN/horus2/ElimGraph.cpp +++ /dev/null @@ -1,243 +0,0 @@ -#include - -#include - -#include "ElimGraph.h" - -ElimHeuristic ElimGraph::elimHeuristic = MIN_NEIGHBORS; - - -ElimGraph::ElimGraph (const vector& factors) -{ - for (size_t i = 0; i < factors.size(); i++) { - if (factors[i] == 0) { // if contained just one var with evidence - continue; - } - const VarIds& vids = factors[i]->arguments(); - for (size_t j = 0; j < vids.size() - 1; j++) { - EgNode* n1 = getEgNode (vids[j]); - if (n1 == 0) { - n1 = new EgNode (vids[j], factors[i]->range (j)); - addNode (n1); - } - for (size_t k = j + 1; k < vids.size(); k++) { - EgNode* n2 = getEgNode (vids[k]); - if (n2 == 0) { - n2 = new EgNode (vids[k], factors[i]->range (k)); - addNode (n2); - } - if (neighbors (n1, n2) == false) { - addEdge (n1, n2); - } - } - } - if (vids.size() == 1) { - if (getEgNode (vids[0]) == 0) { - addNode (new EgNode (vids[0], factors[i]->range (0))); - } - } - } -} - - - -ElimGraph::~ElimGraph (void) -{ - for (size_t i = 0; i < nodes_.size(); i++) { - delete nodes_[i]; - } -} - - - -VarIds -ElimGraph::getEliminatingOrder (const VarIds& exclude) -{ - VarIds elimOrder; - unmarked_.reserve (nodes_.size()); - for (size_t i = 0; i < nodes_.size(); i++) { - if (Util::contains (exclude, nodes_[i]->varId()) == false) { - unmarked_.insert (nodes_[i]); - } - } - size_t nrVarsToEliminate = nodes_.size() - exclude.size(); - for (size_t i = 0; i < nrVarsToEliminate; i++) { - EgNode* node = getLowestCostNode(); - unmarked_.remove (node); - const EGNeighs& neighs = node->neighbors(); - for (size_t j = 0; j < neighs.size(); j++) { - neighs[j]->removeNeighbor (node); - } - elimOrder.push_back (node->varId()); - connectAllNeighbors (node); - } - return elimOrder; -} - - - -void -ElimGraph::print (void) const -{ - for (size_t i = 0; i < nodes_.size(); i++) { - cout << "node " << nodes_[i]->label() << " neighs:" ; - EGNeighs neighs = nodes_[i]->neighbors(); - for (size_t j = 0; j < neighs.size(); j++) { - cout << " " << neighs[j]->label(); - } - cout << endl; - } -} - - - -void -ElimGraph::exportToGraphViz ( - const char* fileName, - bool showNeighborless, - const VarIds& highlightVarIds) const -{ - ofstream out (fileName); - if (!out.is_open()) { - cerr << "Error: couldn't open file '" << fileName << "'." ; - return; - } - out << "strict graph {" << endl; - for (size_t i = 0; i < nodes_.size(); i++) { - if (showNeighborless || nodes_[i]->neighbors().size() != 0) { - out << '"' << nodes_[i]->label() << '"' << endl; - } - } - for (size_t i = 0; i < highlightVarIds.size(); i++) { - EgNode* node =getEgNode (highlightVarIds[i]); - if (node) { - out << '"' << node->label() << '"' ; - out << " [shape=box3d]" << endl; - } else { - cerr << "Error: invalid variable id: " << highlightVarIds[i] << "." ; - cerr << endl; - exit (EXIT_FAILURE); - } - } - for (size_t i = 0; i < nodes_.size(); i++) { - EGNeighs neighs = nodes_[i]->neighbors(); - for (size_t j = 0; j < neighs.size(); j++) { - out << '"' << nodes_[i]->label() << '"' << " -- " ; - out << '"' << neighs[j]->label() << '"' << endl; - } - } - out << "}" << endl; - out.close(); -} - - - -VarIds -ElimGraph::getEliminationOrder ( - const Factors& factors, - VarIds excludedVids) -{ - if (elimHeuristic == ElimHeuristic::SEQUENTIAL) { - VarIds allVids; - Factors::const_iterator first = factors.begin(); - Factors::const_iterator end = factors.end(); - for (; first != end; ++first) { - Util::addToVector (allVids, (*first)->arguments()); - } - TinySet elimOrder (allVids); - elimOrder -= TinySet (excludedVids); - return elimOrder.elements(); - } - ElimGraph graph (factors); - return graph.getEliminatingOrder (excludedVids); -} - - - -void -ElimGraph::addNode (EgNode* n) -{ - nodes_.push_back (n); - n->setIndex (nodes_.size() - 1); - varMap_.insert (make_pair (n->varId(), n)); -} - - - -EgNode* -ElimGraph::getEgNode (VarId vid) const -{ - unordered_map::const_iterator it; - it = varMap_.find (vid); - return (it != varMap_.end()) ? it->second : 0; -} - - - -EgNode* -ElimGraph::getLowestCostNode (void) const -{ - EgNode* bestNode = 0; - unsigned minCost = std::numeric_limits::max(); - EGNeighs::const_iterator it; - switch (elimHeuristic) { - case MIN_NEIGHBORS: { - for (it = unmarked_.begin(); it != unmarked_.end(); ++ it) { - unsigned cost = getNeighborsCost (*it); - if (cost < minCost) { - bestNode = *it; - minCost = cost; - } - }} - break; - case MIN_WEIGHT: { - for (it = unmarked_.begin(); it != unmarked_.end(); ++ it) { - unsigned cost = getWeightCost (*it); - if (cost < minCost) { - bestNode = *it; - minCost = cost; - } - }} - break; - case MIN_FILL: { - for (it = unmarked_.begin(); it != unmarked_.end(); ++ it) { - unsigned cost = getFillCost (*it); - if (cost < minCost) { - bestNode = *it; - minCost = cost; - } - }} - break; - case WEIGHTED_MIN_FILL: { - for (it = unmarked_.begin(); it != unmarked_.end(); ++ it) { - unsigned cost = getWeightedFillCost (*it); - if (cost < minCost) { - bestNode = *it; - minCost = cost; - } - }} - break; - default: - assert (false); - } - assert (bestNode); - return bestNode; -} - - - -void -ElimGraph::connectAllNeighbors (const EgNode* n) -{ - const EGNeighs& neighs = n->neighbors(); - if (neighs.size() > 0) { - for (size_t i = 0; i < neighs.size() - 1; i++) { - for (size_t j = i + 1; j < neighs.size(); j++) { - if ( ! neighbors (neighs[i], neighs[j])) { - addEdge (neighs[i], neighs[j]); - } - } - } - } -} - diff --git a/packages/CLPBN/horus2/ElimGraph.h b/packages/CLPBN/horus2/ElimGraph.h deleted file mode 100644 index 8188b5ba6..000000000 --- a/packages/CLPBN/horus2/ElimGraph.h +++ /dev/null @@ -1,139 +0,0 @@ -#ifndef HORUS_ELIMGRAPH_H -#define HORUS_ELIMGRAPH_H - -#include "unordered_map" - -#include "FactorGraph.h" -#include "TinySet.h" -#include "Horus.h" - - -using namespace std; - -enum ElimHeuristic -{ - SEQUENTIAL, - MIN_NEIGHBORS, - MIN_WEIGHT, - MIN_FILL, - WEIGHTED_MIN_FILL -}; - - -class EgNode; - -typedef TinySet EGNeighs; - - -class EgNode : public Var -{ - public: - EgNode (VarId vid, unsigned range) : Var (vid, range) { } - - void addNeighbor (EgNode* n) { neighs_.insert (n); } - - void removeNeighbor (EgNode* n) { neighs_.remove (n); } - - bool isNeighbor (EgNode* n) const { return neighs_.contains (n); } - - const EGNeighs& neighbors (void) const { return neighs_; } - - private: - EGNeighs neighs_; -}; - - -class ElimGraph -{ - public: - ElimGraph (const Factors&); - - ~ElimGraph (void); - - VarIds getEliminatingOrder (const VarIds&); - - void print (void) const; - - void exportToGraphViz (const char*, bool = true, - const VarIds& = VarIds()) const; - - static VarIds getEliminationOrder (const Factors&, VarIds); - - static ElimHeuristic elimHeuristic; - - private: - - void addEdge (EgNode* n1, EgNode* n2) - { - assert (n1 != n2); - n1->addNeighbor (n2); - n2->addNeighbor (n1); - } - - unsigned getNeighborsCost (const EgNode* n) const - { - return n->neighbors().size(); - } - - unsigned getWeightCost (const EgNode* n) const - { - unsigned cost = 1; - const EGNeighs& neighs = n->neighbors(); - for (size_t i = 0; i < neighs.size(); i++) { - cost *= neighs[i]->range(); - } - return cost; - } - - unsigned getFillCost (const EgNode* n) const - { - unsigned cost = 0; - const EGNeighs& neighs = n->neighbors(); - if (neighs.size() > 0) { - for (size_t i = 0; i < neighs.size() - 1; i++) { - for (size_t j = i + 1; j < neighs.size(); j++) { - if ( ! neighbors (neighs[i], neighs[j])) { - cost ++; - } - } - } - } - return cost; - } - - unsigned getWeightedFillCost (const EgNode* n) const - { - unsigned cost = 0; - const EGNeighs& neighs = n->neighbors(); - if (neighs.size() > 0) { - for (size_t i = 0; i < neighs.size() - 1; i++) { - for (size_t j = i + 1; j < neighs.size(); j++) { - if ( ! neighbors (neighs[i], neighs[j])) { - cost += neighs[i]->range() * neighs[j]->range(); - } - } - } - } - return cost; - } - - bool neighbors (EgNode* n1, EgNode* n2) const - { - return n1->isNeighbor (n2); - } - - void addNode (EgNode*); - - EgNode* getEgNode (VarId) const; - - EgNode* getLowestCostNode (void) const; - - void connectAllNeighbors (const EgNode*); - - vector nodes_; - TinySet unmarked_; - unordered_map varMap_; -}; - -#endif // HORUS_ELIMGRAPH_H - diff --git a/packages/CLPBN/horus2/Factor.cpp b/packages/CLPBN/horus2/Factor.cpp deleted file mode 100644 index 9b8ad0be7..000000000 --- a/packages/CLPBN/horus2/Factor.cpp +++ /dev/null @@ -1,237 +0,0 @@ -#include -#include - -#include - -#include -#include - -#include "Factor.h" -#include "Indexer.h" - - -Factor::Factor (const Factor& g) -{ - clone (g); -} - - - -Factor::Factor ( - const VarIds& vids, - const Ranges& ranges, - const Params& params, - unsigned distId) -{ - args_ = vids; - ranges_ = ranges; - params_ = params; - distId_ = distId; - assert (params_.size() == Util::sizeExpected (ranges_)); -} - - - -Factor::Factor ( - const Vars& vars, - const Params& params, - unsigned distId) -{ - for (size_t i = 0; i < vars.size(); i++) { - args_.push_back (vars[i]->varId()); - ranges_.push_back (vars[i]->range()); - } - params_ = params; - distId_ = distId; - assert (params_.size() == Util::sizeExpected (ranges_)); -} - - - -void -Factor::sumOut (VarId vid) -{ - if (vid == args_.front() && ranges_.front() == 2) { - // optimization - sumOutFirstVariable(); - } else if (vid == args_.back() && ranges_.back() == 2) { - // optimization - sumOutLastVariable(); - } else { - assert (indexOf (vid) != args_.size()); - sumOutIndex (indexOf (vid)); - } -} - - - -void -Factor::sumOutAllExcept (VarId vid) -{ - assert (indexOf (vid) != args_.size()); - sumOutAllExceptIndex (indexOf (vid)); -} - - - -void -Factor::sumOutAllExcept (const VarIds& vids) -{ - vector mask (args_.size(), false); - for (unsigned i = 0; i < vids.size(); i++) { - assert (indexOf (vids[i]) != args_.size()); - mask[indexOf (vids[i])] = true; - } - sumOutArgs (mask); -} - - - -void -Factor::sumOutAllExceptIndex (size_t idx) -{ - assert (idx < args_.size()); - vector mask (args_.size(), false); - mask[idx] = true; - sumOutArgs (mask); -} - - -void -Factor::multiply (Factor& g) -{ - if (args_.size() == 0) { - clone (g); - return; - } - TFactor::multiply (g); -} - - - -string -Factor::getLabel (void) const -{ - stringstream ss; - ss << "f(" ; - for (size_t i = 0; i < args_.size(); i++) { - if (i != 0) ss << "," ; - ss << Var (args_[i], ranges_[i]).label(); - } - ss << ")" ; - return ss.str(); -} - - - -void -Factor::print (void) const -{ - Vars vars; - for (size_t i = 0; i < args_.size(); i++) { - vars.push_back (new Var (args_[i], ranges_[i])); - } - vector jointStrings = Util::getStateLines (vars); - for (size_t i = 0; i < params_.size(); i++) { - // cout << "[" << distId_ << "] " ; - cout << "f(" << jointStrings[i] << ")" ; - cout << " = " << params_[i] << endl; - } - cout << endl; - for (size_t i = 0; i < vars.size(); i++) { - delete vars[i]; - } -} - - - -void -Factor::sumOutFirstVariable (void) -{ - size_t sep = params_.size() / 2; - if (Globals::logDomain) { - std::transform ( - params_.begin(), params_.begin() + sep, - params_.begin() + sep, params_.begin(), - Util::logSum); - - } else { - std::transform ( - params_.begin(), params_.begin() + sep, - params_.begin() + sep, params_.begin(), - std::plus()); - } - params_.resize (sep); - args_.erase (args_.begin()); - ranges_.erase (ranges_.begin()); -} - - - -void -Factor::sumOutLastVariable (void) -{ - Params::iterator first1 = params_.begin(); - Params::iterator first2 = params_.begin(); - Params::iterator last = params_.end(); - if (Globals::logDomain) { - while (first2 != last) { - // the arguments can be swaped, but that is ok - *first1++ = Util::logSum (*first2++, *first2++); - } - } else { - while (first2 != last) { - *first1++ = (*first2++) + (*first2++); - } - } - params_.resize (params_.size() / 2); - args_.pop_back(); - ranges_.pop_back(); -} - - - -void -Factor::sumOutArgs (const vector& mask) -{ - assert (mask.size() == args_.size()); - size_t new_size = 1; - Ranges oldRanges = ranges_; - args_.clear(); - ranges_.clear(); - for (unsigned i = 0; i < mask.size(); i++) { - if (mask[i]) { - new_size *= ranges_[i]; - args_.push_back (args_[i]); - ranges_.push_back (ranges_[i]); - } - } - Params newps (new_size, LogAware::addIdenty()); - Params::const_iterator first = params_.begin(); - Params::const_iterator last = params_.end(); - MapIndexer indexer (oldRanges, mask); - if (Globals::logDomain) { - while (first != last) { - newps[indexer] = Util::logSum (newps[indexer], *first++); - ++ indexer; - } - } else { - while (first != last) { - newps[indexer] += *first++; - ++ indexer; - } - } - params_ = newps; -} - - - -void -Factor::clone (const Factor& g) -{ - args_ = g.arguments(); - ranges_ = g.ranges(); - params_ = g.params(); - distId_ = g.distId(); -} - diff --git a/packages/CLPBN/horus2/Factor.h b/packages/CLPBN/horus2/Factor.h deleted file mode 100644 index 742f20f7a..000000000 --- a/packages/CLPBN/horus2/Factor.h +++ /dev/null @@ -1,294 +0,0 @@ -#ifndef HORUS_FACTOR_H -#define HORUS_FACTOR_H - -#include - -#include "Var.h" -#include "Indexer.h" -#include "Util.h" - - -using namespace std; - - -template -class TFactor -{ - public: - const vector& arguments (void) const { return args_; } - - vector& arguments (void) { return args_; } - - const Ranges& ranges (void) const { return ranges_; } - - const Params& params (void) const { return params_; } - - Params& params (void) { return params_; } - - size_t nrArguments (void) const { return args_.size(); } - - size_t size (void) const { return params_.size(); } - - unsigned distId (void) const { return distId_; } - - void setDistId (unsigned id) { distId_ = id; } - - void normalize (void) { LogAware::normalize (params_); } - - void randomize (void) - { - for (size_t i = 0; i < params_.size(); ++i) { - params_[i] = (double) std::rand() / RAND_MAX; - } - } - - void setParams (const Params& newParams) - { - params_ = newParams; - assert (params_.size() == Util::sizeExpected (ranges_)); - } - - size_t indexOf (const T& t) const - { - return Util::indexOf (args_, t); - } - - const T& argument (size_t idx) const - { - assert (idx < args_.size()); - return args_[idx]; - } - - T& argument (size_t idx) - { - assert (idx < args_.size()); - return args_[idx]; - } - - unsigned range (size_t idx) const - { - assert (idx < ranges_.size()); - return ranges_[idx]; - } - - void multiply (TFactor& g) - { - if (args_ == g.arguments()) { - // optimization - Globals::logDomain - ? params_ += g.params() - : params_ *= g.params(); - return; - } - unsigned range_prod = 1; - bool share_arguments = false; - const vector& g_args = g.arguments(); - const Ranges& g_ranges = g.ranges(); - const Params& g_params = g.params(); - for (size_t i = 0; i < g_args.size(); i++) { - size_t idx = indexOf (g_args[i]); - if (idx == args_.size()) { - range_prod *= g_ranges[i]; - args_.push_back (g_args[i]); - ranges_.push_back (g_ranges[i]); - } else { - share_arguments = true; - } - } - if (share_arguments == false) { - // optimization - cartesianProduct (g_params.begin(), g_params.end()); - } else { - extend (range_prod); - Params::iterator it = params_.begin(); - MapIndexer indexer (args_, ranges_, g_args, g_ranges); - if (Globals::logDomain) { - for (; indexer.valid(); ++it, ++indexer) { - *it += g_params[indexer]; - } - } else { - for (; indexer.valid(); ++it, ++indexer) { - *it *= g_params[indexer]; - } - } - } - } - - void sumOutIndex (size_t idx) - { - assert (idx < args_.size()); - assert (args_.size() > 1); - size_t new_size = params_.size() / ranges_[idx]; - Params newps (new_size, LogAware::addIdenty()); - Params::const_iterator first = params_.begin(); - Params::const_iterator last = params_.end(); - MapIndexer indexer (ranges_, idx); - if (Globals::logDomain) { - for (; first != last; ++indexer) { - newps[indexer] = Util::logSum (newps[indexer], *first++); - } - } else { - for (; first != last; ++indexer) { - newps[indexer] += *first++; - } - } - params_ = newps; - args_.erase (args_.begin() + idx); - ranges_.erase (ranges_.begin() + idx); - } - - void absorveEvidence (const T& arg, unsigned obsIdx) - { - size_t idx = indexOf (arg); - assert (idx != args_.size()); - assert (obsIdx < ranges_[idx]); - Params newps; - newps.reserve (params_.size() / ranges_[idx]); - Indexer indexer (ranges_); - for (unsigned i = 0; i < obsIdx; ++i) { - indexer.incrementDimension (idx); - } - while (indexer.valid()) { - newps.push_back (params_[indexer]); - indexer.incrementExceptDimension (idx); - } - params_ = newps; - args_.erase (args_.begin() + idx); - ranges_.erase (ranges_.begin() + idx); - } - - void reorderArguments (const vector new_args) - { - assert (new_args.size() == args_.size()); - if (new_args == args_) { - return; // already on the desired order - } - Ranges new_ranges; - for (size_t i = 0; i < new_args.size(); i++) { - size_t idx = indexOf (new_args[i]); - assert (idx != args_.size()); - new_ranges.push_back (ranges_[idx]); - } - Params newps; - newps.reserve (params_.size()); - MapIndexer indexer (new_args, new_ranges, args_, ranges_); - for (; indexer.valid(); ++indexer) { - newps.push_back (params_[indexer]); - } - params_ = newps; - args_ = new_args; - ranges_ = new_ranges; - } - - bool contains (const T& arg) const - { - return Util::contains (args_, arg); - } - - bool contains (const vector& args) const - { - for (size_t i = 0; i < args.size(); i++) { - if (contains (args[i]) == false) { - return false; - } - } - return true; - } - - double& operator[] (size_t idx) - { - assert (idx < params_.size()); - return params_[idx]; - } - - - protected: - vector args_; - Ranges ranges_; - Params params_; - unsigned distId_; - - private: - void extend (unsigned range_prod) - { - Params backup = params_; - params_.clear(); - params_.reserve (backup.size() * range_prod); - Params::const_iterator first = backup.begin(); - Params::const_iterator last = backup.end(); - for (; first != last; ++first) { - for (unsigned reps = 0; reps < range_prod; ++reps) { - params_.push_back (*first); - } - } - } - - void cartesianProduct ( - Params::const_iterator first2, - Params::const_iterator last2) - { - Params backup = params_; - params_.clear(); - params_.reserve (params_.size() * (last2 - first2)); - Params::const_iterator first1 = backup.begin(); - Params::const_iterator last1 = backup.end(); - Params::const_iterator tmp; - if (Globals::logDomain) { - for (; first1 != last1; ++first1) { - for (tmp = first2; tmp != last2; ++tmp) { - params_.push_back ((*first1) + (*tmp)); - } - } - } else { - for (; first1 != last1; ++first1) { - for (tmp = first2; tmp != last2; ++tmp) { - params_.push_back ((*first1) * (*tmp)); - } - } - } - } - -}; - - - -class Factor : public TFactor -{ - public: - Factor (void) { } - - Factor (const Factor&); - - Factor (const VarIds&, const Ranges&, const Params&, - unsigned = Util::maxUnsigned()); - - Factor (const Vars&, const Params&, - unsigned = Util::maxUnsigned()); - - void sumOut (VarId); - - void sumOutAllExcept (VarId); - - void sumOutAllExcept (const VarIds&); - - void sumOutAllExceptIndex (size_t idx); - - void multiply (Factor&); - - string getLabel (void) const; - - void print (void) const; - - private: - void sumOutFirstVariable (void); - - void sumOutLastVariable (void); - - void sumOutArgs (const vector& mask); - - void clone (const Factor& f); - -}; - -#endif // HORUS_FACTOR_H - diff --git a/packages/CLPBN/horus2/FactorGraph.cpp b/packages/CLPBN/horus2/FactorGraph.cpp deleted file mode 100644 index ba31a9faa..000000000 --- a/packages/CLPBN/horus2/FactorGraph.cpp +++ /dev/null @@ -1,454 +0,0 @@ -#include -#include -#include - -#include -#include -#include - -#include "FactorGraph.h" -#include "Factor.h" -#include "BayesBall.h" -#include "Util.h" - - -FactorGraph::FactorGraph (const FactorGraph& fg) -{ - const VarNodes& varNodes = fg.varNodes(); - for (size_t i = 0; i < varNodes.size(); i++) { - addVarNode (new VarNode (varNodes[i])); - } - const FacNodes& facNodes = fg.facNodes(); - for (size_t i = 0; i < facNodes.size(); i++) { - FacNode* facNode = new FacNode (facNodes[i]->factor()); - addFacNode (facNode); - const VarNodes& neighs = facNodes[i]->neighbors(); - for (size_t j = 0; j < neighs.size(); j++) { - addEdge (varNodes_[neighs[j]->getIndex()], facNode); - } - } - bayesFactors_ = fg.bayesianFactors(); -} - - - -void -FactorGraph::readFromUaiFormat (const char* fileName) -{ - std::ifstream is (fileName); - if (!is.is_open()) { - cerr << "Error: couldn't open file '" << fileName << "'." ; - exit (EXIT_FAILURE); - } - ignoreLines (is); - string line; - getline (is, line); - if (line != "MARKOV") { - cerr << "Error: the network must be a MARKOV network." << endl; - exit (EXIT_FAILURE); - } - // read the number of vars - ignoreLines (is); - unsigned nrVars; - is >> nrVars; - // read the range of each var - ignoreLines (is); - Ranges ranges (nrVars); - for (unsigned i = 0; i < nrVars; i++) { - is >> ranges[i]; - } - unsigned nrFactors; - unsigned nrArgs; - unsigned vid; - is >> nrFactors; - vector factorVarIds; - vector factorRanges; - for (unsigned i = 0; i < nrFactors; i++) { - ignoreLines (is); - is >> nrArgs; - factorVarIds.push_back ({ }); - factorRanges.push_back ({ }); - for (unsigned j = 0; j < nrArgs; j++) { - is >> vid; - if (vid >= ranges.size()) { - cerr << "Error: invalid variable identifier `" << vid << "'. " ; - cerr << "Identifiers must be between 0 and " << ranges.size() - 1 ; - cerr << "." << endl; - exit (EXIT_FAILURE); - } - factorVarIds.back().push_back (vid); - factorRanges.back().push_back (ranges[vid]); - } - } - // read the parameters - unsigned nrParams; - for (unsigned i = 0; i < nrFactors; i++) { - ignoreLines (is); - is >> nrParams; - if (nrParams != Util::sizeExpected (factorRanges[i])) { - cerr << "Error: invalid number of parameters for factor nº " << i ; - cerr << ", " << Util::sizeExpected (factorRanges[i]); - cerr << " expected, " << nrParams << " given." << endl; - exit (EXIT_FAILURE); - } - Params params (nrParams); - for (unsigned j = 0; j < nrParams; j++) { - is >> params[j]; - } - if (Globals::logDomain) { - Util::log (params); - } - addFactor (Factor (factorVarIds[i], factorRanges[i], params)); - } - is.close(); -} - - - -void -FactorGraph::readFromLibDaiFormat (const char* fileName) -{ - std::ifstream is (fileName); - if (!is.is_open()) { - cerr << "Error: couldn't open file '" << fileName << "'." ; - exit (EXIT_FAILURE); - } - ignoreLines (is); - unsigned nrFactors; - unsigned nrArgs; - VarId vid; - is >> nrFactors; - for (unsigned i = 0; i < nrFactors; i++) { - ignoreLines (is); - // read the factor arguments - is >> nrArgs; - VarIds vids; - for (unsigned j = 0; j < nrArgs; j++) { - ignoreLines (is); - is >> vid; - vids.push_back (vid); - } - // read ranges - Ranges ranges (nrArgs); - for (unsigned j = 0; j < nrArgs; j++) { - ignoreLines (is); - is >> ranges[j]; - VarNode* var = getVarNode (vids[j]); - if (var != 0 && ranges[j] != var->range()) { - cerr << "Error: variable `" << vids[j] << "' appears in two or " ; - cerr << "more factors with a different range." << endl; - } - } - // read parameters - ignoreLines (is); - unsigned nNonzeros; - is >> nNonzeros; - Params params (Util::sizeExpected (ranges), 0); - for (unsigned j = 0; j < nNonzeros; j++) { - ignoreLines (is); - unsigned index; - is >> index; - ignoreLines (is); - double val; - is >> val; - params[index] = val; - } - if (Globals::logDomain) { - Util::log (params); - } - std::reverse (vids.begin(), vids.end()); - Factor f (vids, ranges, params); - std::reverse (vids.begin(), vids.end()); - f.reorderArguments (vids); - addFactor (f); - } - is.close(); -} - - - -FactorGraph::~FactorGraph (void) -{ - for (size_t i = 0; i < varNodes_.size(); i++) { - delete varNodes_[i]; - } - for (size_t i = 0; i < facNodes_.size(); i++) { - delete facNodes_[i]; - } -} - - - -void -FactorGraph::addFactor (const Factor& factor) -{ - FacNode* fn = new FacNode (factor); - addFacNode (fn); - const VarIds& vids = fn->factor().arguments(); - for (size_t i = 0; i < vids.size(); i++) { - VarMap::const_iterator it = varMap_.find (vids[i]); - if (it != varMap_.end()) { - addEdge (it->second, fn); - } else { - VarNode* vn = new VarNode (vids[i], fn->factor().range (i)); - addVarNode (vn); - addEdge (vn, fn); - } - } -} - - - -void -FactorGraph::addVarNode (VarNode* vn) -{ - varNodes_.push_back (vn); - vn->setIndex (varNodes_.size() - 1); - varMap_.insert (make_pair (vn->varId(), vn)); -} - - - -void -FactorGraph::addFacNode (FacNode* fn) -{ - facNodes_.push_back (fn); - fn->setIndex (facNodes_.size() - 1); -} - - - -void -FactorGraph::addEdge (VarNode* vn, FacNode* fn) -{ - vn->addNeighbor (fn); - fn->addNeighbor (vn); -} - - - -bool -FactorGraph::isTree (void) const -{ - return !containsCycle(); -} - - - -BayesBallGraph& -FactorGraph::getStructure (void) -{ - assert (bayesFactors_); - if (structure_.empty()) { - for (size_t i = 0; i < varNodes_.size(); i++) { - structure_.addNode (new BBNode (varNodes_[i])); - } - for (size_t i = 0; i < facNodes_.size(); i++) { - const VarIds& vids = facNodes_[i]->factor().arguments(); - for (size_t j = 1; j < vids.size(); j++) { - structure_.addEdge (vids[j], vids[0]); - } - } - } - return structure_; -} - - - -void -FactorGraph::print (void) const -{ - for (size_t i = 0; i < varNodes_.size(); i++) { - cout << "var id = " << varNodes_[i]->varId() << endl; - cout << "label = " << varNodes_[i]->label() << endl; - cout << "range = " << varNodes_[i]->range() << endl; - cout << "evidence = " << varNodes_[i]->getEvidence() << endl; - cout << "factors = " ; - for (size_t j = 0; j < varNodes_[i]->neighbors().size(); j++) { - cout << varNodes_[i]->neighbors()[j]->getLabel() << " " ; - } - cout << endl << endl; - } - for (size_t i = 0; i < facNodes_.size(); i++) { - facNodes_[i]->factor().print(); - } -} - - - -void -FactorGraph::exportToGraphViz (const char* fileName) const -{ - ofstream out (fileName); - if (!out.is_open()) { - cerr << "Error: couldn't open file '" << fileName << "'." ; - return; - } - out << "graph \"" << fileName << "\" {" << endl; - for (size_t i = 0; i < varNodes_.size(); i++) { - if (varNodes_[i]->hasEvidence()) { - out << '"' << varNodes_[i]->label() << '"' ; - out << " [style=filled, fillcolor=yellow]" << endl; - } - } - for (size_t i = 0; i < facNodes_.size(); i++) { - out << '"' << facNodes_[i]->getLabel() << '"' ; - out << " [label=\"" << facNodes_[i]->getLabel(); - out << "\"" << ", shape=box]" << endl; - } - for (size_t i = 0; i < facNodes_.size(); i++) { - const VarNodes& myVars = facNodes_[i]->neighbors(); - for (size_t j = 0; j < myVars.size(); j++) { - out << '"' << facNodes_[i]->getLabel() << '"' ; - out << " -- " ; - out << '"' << myVars[j]->label() << '"' << endl; - } - } - out << "}" << endl; - out.close(); -} - - - -void -FactorGraph::exportToUaiFormat (const char* fileName) const -{ - ofstream out (fileName); - if (!out.is_open()) { - cerr << "Error: couldn't open file '" << fileName << "'." ; - return; - } - out << "MARKOV" << endl; - out << varNodes_.size() << endl; - VarNodes sortedVns = varNodes_; - std::sort (sortedVns.begin(), sortedVns.end(), sortByVarId()); - for (size_t i = 0; i < sortedVns.size(); i++) { - out << ((i != 0) ? " " : "") << sortedVns[i]->range(); - } - out << endl << facNodes_.size() << endl; - for (size_t i = 0; i < facNodes_.size(); i++) { - VarIds args = facNodes_[i]->factor().arguments(); - out << args.size() << " " << Util::elementsToString (args) << endl; - } - out << endl; - for (size_t i = 0; i < facNodes_.size(); i++) { - Params params = facNodes_[i]->factor().params(); - if (Globals::logDomain) { - Util::exp (params); - } - out << params.size() << endl << " " ; - out << Util::elementsToString (params) << endl << endl; - } - out.close(); -} - - - -void -FactorGraph::exportToLibDaiFormat (const char* fileName) const -{ - ofstream out (fileName); - if (!out.is_open()) { - cerr << "Error: couldn't open file '" << fileName << "'." ; - return; - } - out << facNodes_.size() << endl << endl; - for (size_t i = 0; i < facNodes_.size(); i++) { - Factor f (facNodes_[i]->factor()); - out << f.nrArguments() << endl; - out << Util::elementsToString (f.arguments()) << endl; - out << Util::elementsToString (f.ranges()) << endl; - VarIds args = f.arguments(); - std::reverse (args.begin(), args.end()); - f.reorderArguments (args); - if (Globals::logDomain) { - Util::exp (f.params()); - } - out << f.size() << endl; - for (size_t j = 0; j < f.size(); j++) { - out << j << " " << f[j] << endl; - } - out << endl; - } - out.close(); -} - - - -void -FactorGraph::ignoreLines (std::ifstream& is) const -{ - string ignoreStr; - while (is.peek() == '#' || is.peek() == '\n') { - getline (is, ignoreStr); - } -} - - - -bool -FactorGraph::containsCycle (void) const -{ - vector visitedVars (varNodes_.size(), false); - vector visitedFactors (facNodes_.size(), false); - for (size_t i = 0; i < varNodes_.size(); i++) { - int v = varNodes_[i]->getIndex(); - if (!visitedVars[v]) { - if (containsCycle (varNodes_[i], 0, visitedVars, visitedFactors)) { - return true; - } - } - } - return false; -} - - - -bool -FactorGraph::containsCycle ( - const VarNode* v, - const FacNode* p, - vector& visitedVars, - vector& visitedFactors) const -{ - visitedVars[v->getIndex()] = true; - const FacNodes& adjacencies = v->neighbors(); - for (size_t i = 0; i < adjacencies.size(); i++) { - int w = adjacencies[i]->getIndex(); - if (!visitedFactors[w]) { - if (containsCycle (adjacencies[i], v, visitedVars, visitedFactors)) { - return true; - } - } - else if (visitedFactors[w] && adjacencies[i] != p) { - return true; - } - } - return false; // no cycle detected in this component -} - - - -bool -FactorGraph::containsCycle ( - const FacNode* v, - const VarNode* p, - vector& visitedVars, - vector& visitedFactors) const -{ - visitedFactors[v->getIndex()] = true; - const VarNodes& adjacencies = v->neighbors(); - for (size_t i = 0; i < adjacencies.size(); i++) { - int w = adjacencies[i]->getIndex(); - if (!visitedVars[w]) { - if (containsCycle (adjacencies[i], v, visitedVars, visitedFactors)) { - return true; - } - } - else if (visitedVars[w] && adjacencies[i] != p) { - return true; - } - } - return false; // no cycle detected in this component -} - diff --git a/packages/CLPBN/horus2/FactorGraph.h b/packages/CLPBN/horus2/FactorGraph.h deleted file mode 100644 index b2b03369d..000000000 --- a/packages/CLPBN/horus2/FactorGraph.h +++ /dev/null @@ -1,150 +0,0 @@ -#ifndef HORUS_FACTORGRAPH_H -#define HORUS_FACTORGRAPH_H - -#include - -#include "Factor.h" -#include "BayesBallGraph.h" -#include "Horus.h" - -using namespace std; - - -class FacNode; - -class VarNode : public Var -{ - public: - VarNode (VarId varId, unsigned nrStates, - int evidence = Constants::NO_EVIDENCE) - : Var (varId, nrStates, evidence) { } - - VarNode (const Var* v) : Var (v) { } - - void addNeighbor (FacNode* fn) { neighs_.push_back (fn); } - - const FacNodes& neighbors (void) const { return neighs_; } - - private: - DISALLOW_COPY_AND_ASSIGN (VarNode); - - FacNodes neighs_; -}; - - - -class FacNode -{ - public: - FacNode (const Factor& f) : factor_(f), index_(-1) { } - - const Factor& factor (void) const { return factor_; } - - Factor& factor (void) { return factor_; } - - void addNeighbor (VarNode* vn) { neighs_.push_back (vn); } - - const VarNodes& neighbors (void) const { return neighs_; } - - size_t getIndex (void) const { return index_; } - - void setIndex (size_t index) { index_ = index; } - - string getLabel (void) { return factor_.getLabel(); } - - private: - DISALLOW_COPY_AND_ASSIGN (FacNode); - - VarNodes neighs_; - Factor factor_; - size_t index_; -}; - - - -class FactorGraph -{ - public: - FactorGraph (void) : bayesFactors_(false) { } - - FactorGraph (const FactorGraph&); - - ~FactorGraph (void); - - const VarNodes& varNodes (void) const { return varNodes_; } - - const FacNodes& facNodes (void) const { return facNodes_; } - - void setFactorsAsBayesian (void) { bayesFactors_ = true; } - - bool bayesianFactors (void) const { return bayesFactors_; } - - size_t nrVarNodes (void) const { return varNodes_.size(); } - - size_t nrFacNodes (void) const { return facNodes_.size(); } - - VarNode* getVarNode (VarId vid) const - { - VarMap::const_iterator it = varMap_.find (vid); - return it != varMap_.end() ? it->second : 0; - } - - void readFromUaiFormat (const char*); - - void readFromLibDaiFormat (const char*); - - void addFactor (const Factor& factor); - - void addVarNode (VarNode*); - - void addFacNode (FacNode*); - - void addEdge (VarNode*, FacNode*); - - bool isTree (void) const; - - BayesBallGraph& getStructure (void); - - void print (void) const; - - void exportToGraphViz (const char*) const; - - void exportToUaiFormat (const char*) const; - - void exportToLibDaiFormat (const char*) const; - - private: - // DISALLOW_COPY_AND_ASSIGN (FactorGraph); - - void ignoreLines (std::ifstream&) const; - - bool containsCycle (void) const; - - bool containsCycle (const VarNode*, const FacNode*, - vector&, vector&) const; - - bool containsCycle (const FacNode*, const VarNode*, - vector&, vector&) const; - - VarNodes varNodes_; - FacNodes facNodes_; - - BayesBallGraph structure_; - bool bayesFactors_; - - typedef unordered_map VarMap; - VarMap varMap_; -}; - - - -struct sortByVarId -{ - bool operator()(VarNode* vn1, VarNode* vn2) { - return vn1->varId() < vn2->varId(); - } -}; - - -#endif // HORUS_FACTORGRAPH_H - diff --git a/packages/CLPBN/horus2/GroundSolver.cpp b/packages/CLPBN/horus2/GroundSolver.cpp deleted file mode 100644 index 4cd3fdbd2..000000000 --- a/packages/CLPBN/horus2/GroundSolver.cpp +++ /dev/null @@ -1,107 +0,0 @@ -#include "GroundSolver.h" -#include "Util.h" -#include "BeliefProp.h" -#include "CountingBp.h" -#include "VarElim.h" - - -void -GroundSolver::printAnswer (const VarIds& vids) -{ - Vars unobservedVars; - VarIds unobservedVids; - for (size_t i = 0; i < vids.size(); i++) { - VarNode* vn = fg.getVarNode (vids[i]); - if (vn->hasEvidence() == false) { - unobservedVars.push_back (vn); - unobservedVids.push_back (vids[i]); - } - } - if (unobservedVids.empty() == false) { - Params res = solveQuery (unobservedVids); - vector stateLines = Util::getStateLines (unobservedVars); - for (size_t i = 0; i < res.size(); i++) { - cout << "P(" << stateLines[i] << ") = " ; - cout << std::setprecision (Constants::PRECISION) << res[i]; - cout << endl; - } - cout << endl; - } -} - - - -void -GroundSolver::printAllPosterioris (void) -{ - VarNodes vars = fg.varNodes(); - std::sort (vars.begin(), vars.end(), sortByVarId()); - for (size_t i = 0; i < vars.size(); i++) { - printAnswer ({vars[i]->varId()}); - } -} - - - -Params -GroundSolver::getJointByConditioning ( - GroundSolverType solverType, - FactorGraph fg, - const VarIds& jointVarIds) const -{ - VarNodes jointVars; - for (size_t i = 0; i < jointVarIds.size(); i++) { - assert (fg.getVarNode (jointVarIds[i])); - jointVars.push_back (fg.getVarNode (jointVarIds[i])); - } - - GroundSolver* solver = 0; - switch (solverType) { - case GroundSolverType::BP: solver = new BeliefProp (fg); break; - case GroundSolverType::CBP: solver = new CountingBp (fg); break; - case GroundSolverType::VE: solver = new VarElim (fg); break; - } - Params prevBeliefs = solver->solveQuery ({jointVarIds[0]}); - VarIds observedVids = {jointVars[0]->varId()}; - - for (size_t i = 1; i < jointVarIds.size(); i++) { - assert (jointVars[i]->hasEvidence() == false); - Params newBeliefs; - Vars observedVars; - Ranges observedRanges; - for (size_t j = 0; j < observedVids.size(); j++) { - observedVars.push_back (fg.getVarNode (observedVids[j])); - observedRanges.push_back (observedVars.back()->range()); - } - Indexer indexer (observedRanges, false); - while (indexer.valid()) { - for (size_t j = 0; j < observedVars.size(); j++) { - observedVars[j]->setEvidence (indexer[j]); - } - delete solver; - switch (solverType) { - case GroundSolverType::BP: solver = new BeliefProp (fg); break; - case GroundSolverType::CBP: solver = new CountingBp (fg); break; - case GroundSolverType::VE: solver = new VarElim (fg); break; - } - Params beliefs = solver->solveQuery ({jointVarIds[i]}); - for (size_t k = 0; k < beliefs.size(); k++) { - newBeliefs.push_back (beliefs[k]); - } - ++ indexer; - } - - int count = -1; - for (size_t j = 0; j < newBeliefs.size(); j++) { - if (j % jointVars[i]->range() == 0) { - count ++; - } - newBeliefs[j] *= prevBeliefs[count]; - } - prevBeliefs = newBeliefs; - observedVids.push_back (jointVars[i]->varId()); - } - delete solver; - return prevBeliefs; -} - diff --git a/packages/CLPBN/horus2/GroundSolver.h b/packages/CLPBN/horus2/GroundSolver.h deleted file mode 100644 index 18b81454b..000000000 --- a/packages/CLPBN/horus2/GroundSolver.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef HORUS_GROUNDSOLVER_H -#define HORUS_GROUNDSOLVER_H - -#include - -#include "FactorGraph.h" -#include "Var.h" -#include "Horus.h" - - -using namespace std; - -class GroundSolver -{ - public: - GroundSolver (const FactorGraph& factorGraph) : fg(factorGraph) { } - - virtual ~GroundSolver() { } // ensure that subclass destructor is called - - virtual Params solveQuery (VarIds queryVids) = 0; - - virtual void printSolverFlags (void) const = 0; - - void printAnswer (const VarIds& vids); - - void printAllPosterioris (void); - - Params getJointByConditioning (GroundSolverType, - FactorGraph, const VarIds& jointVarIds) const; - - protected: - const FactorGraph& fg; -}; - -#endif // HORUS_GROUNDSOLVER_H - diff --git a/packages/CLPBN/horus2/Histogram.cpp b/packages/CLPBN/horus2/Histogram.cpp deleted file mode 100644 index a9e96cfdd..000000000 --- a/packages/CLPBN/horus2/Histogram.cpp +++ /dev/null @@ -1,146 +0,0 @@ -#include - -#include -#include - -#include "Histogram.h" -#include "Util.h" - - -HistogramSet::HistogramSet (unsigned size, unsigned range) -{ - size_ = size; - hist_.resize (range, 0); - hist_[0] = size; -} - - - -void -HistogramSet::nextHistogram (void) -{ - for (size_t i = hist_.size() - 1; i-- > 0; ) { - if (hist_[i] > 0) { - hist_[i] --; - hist_[i + 1] = maxCount (i + 1); - clearAfter (i + 1); - break; - } - } - assert (std::accumulate (hist_.begin(), hist_.end(), 0) - == (int) size_); -} - - - -unsigned -HistogramSet::operator[] (size_t idx) const -{ - assert (idx < hist_.size()); - return hist_[idx]; -} - - - -unsigned -HistogramSet::nrHistograms (void) const -{ - return HistogramSet::nrHistograms (size_, hist_.size()); -} - - - -void -HistogramSet::reset (void) -{ - std::fill (hist_.begin() + 1, hist_.end(), 0); - hist_[0] = size_; -} - - - -vector -HistogramSet::getHistograms (unsigned N, unsigned R) -{ - HistogramSet hs (N, R); - unsigned H = hs.nrHistograms(); - vector histograms; - histograms.reserve (H); - for (unsigned i = 0; i < H; i++) { - histograms.push_back (hs.hist_); - hs.nextHistogram(); - } - return histograms; -} - - - -unsigned -HistogramSet::nrHistograms (unsigned N, unsigned R) -{ - return Util::nrCombinations (N + R - 1, R - 1); -} - - - -size_t -HistogramSet::findIndex ( - const Histogram& h, - const vector& hists) -{ - vector::const_iterator it = std::lower_bound ( - hists.begin(), hists.end(), h, std::greater()); - assert (it != hists.end() && *it == h); - return std::distance (hists.begin(), it); -} - - - -vector -HistogramSet::getNumAssigns (unsigned N, unsigned R) -{ - HistogramSet hs (N, R); - double N_fac = Util::logFactorial (N); - unsigned H = hs.nrHistograms(); - vector numAssigns; - numAssigns.reserve (H); - for (unsigned h = 0; h < H; h++) { - double prod = 0.0; - for (unsigned r = 0; r < R; r++) { - prod += Util::logFactorial (hs[r]); - } - double res = N_fac - prod; - numAssigns.push_back (Globals::logDomain ? res : std::exp (res)); - hs.nextHistogram(); - } - return numAssigns; -} - - - -ostream& operator<< (ostream &os, const HistogramSet& hs) -{ - os << "#" << hs.hist_; - return os; -} - - - -unsigned -HistogramSet::maxCount (size_t idx) const -{ - unsigned sum = 0; - for (size_t i = 0; i < idx; i++) { - sum += hist_[i]; - } - return size_ - sum; -} - - - -void -HistogramSet::clearAfter (size_t idx) -{ - std::fill (hist_.begin() + idx + 1, hist_.end(), 0); -} - diff --git a/packages/CLPBN/horus2/Histogram.h b/packages/CLPBN/horus2/Histogram.h deleted file mode 100644 index af0c4595e..000000000 --- a/packages/CLPBN/horus2/Histogram.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef HORUS_HISTOGRAM_H -#define HORUS_HISTOGRAM_H - -#include -#include - -using namespace std; - -typedef vector Histogram; - -class HistogramSet -{ - public: - HistogramSet (unsigned, unsigned); - - void nextHistogram (void); - - unsigned operator[] (size_t idx) const; - - unsigned nrHistograms (void) const; - - void reset (void); - - static vector getHistograms (unsigned ,unsigned); - - static unsigned nrHistograms (unsigned, unsigned); - - static size_t findIndex ( - const Histogram&, const vector&); - - static vector getNumAssigns (unsigned, unsigned); - - friend std::ostream& operator<< (ostream &os, const HistogramSet& hs); - - private: - unsigned maxCount (size_t) const; - - void clearAfter (size_t); - - unsigned size_; - Histogram hist_; -}; - -#endif // HORUS_HISTOGRAM_H - diff --git a/packages/CLPBN/horus2/Horus.h b/packages/CLPBN/horus2/Horus.h deleted file mode 100644 index 7e5f12c8e..000000000 --- a/packages/CLPBN/horus2/Horus.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef HORUS_HORUS_H -#define HORUS_HORUS_H - -#include - -#include - -#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) - -using namespace std; - -class Var; -class Factor; -class VarNode; -class FacNode; - -typedef vector Params; -typedef unsigned VarId; -typedef vector VarIds; -typedef vector Vars; -typedef vector VarNodes; -typedef vector FacNodes; -typedef vector Factors; -typedef vector States; -typedef vector Ranges; -typedef unsigned long long ullong; - - -enum LiftedSolverType -{ - LVE, // generalized counting first-order variable elimination (GC-FOVE) - LBP, // lifted first-order belief propagation - LKC // lifted first-order knowledge compilation -}; - - -enum GroundSolverType -{ - VE, // variable elimination - BP, // belief propagation - CBP // counting belief propagation -}; - - -namespace Globals { - -extern bool logDomain; - -// level of debug information -extern unsigned verbosity; - -extern LiftedSolverType liftedSolver; -extern GroundSolverType groundSolver; - -}; - - -namespace Constants { - -// show message calculation for belief propagation -const bool SHOW_BP_CALCS = false; - -const int NO_EVIDENCE = -1; - -// number of digits to show when printing a parameter -const unsigned PRECISION = 6; - -}; - - -namespace BpOptions -{ - enum Schedule { - SEQ_FIXED, - SEQ_RANDOM, - PARALLEL, - MAX_RESIDUAL - }; - extern Schedule schedule; - extern double accuracy; - extern unsigned maxIter; -} - -#endif // HORUS_HORUS_H - diff --git a/packages/CLPBN/horus2/HorusCli.cpp b/packages/CLPBN/horus2/HorusCli.cpp deleted file mode 100644 index 520603052..000000000 --- a/packages/CLPBN/horus2/HorusCli.cpp +++ /dev/null @@ -1,187 +0,0 @@ -#include - -#include -#include - -#include "FactorGraph.h" -#include "VarElim.h" -#include "BeliefProp.h" -#include "CountingBp.h" - -using namespace std; - -int readHorusFlags (int, const char* []); -void readFactorGraph (FactorGraph&, const char*); -VarIds readQueryAndEvidence (FactorGraph&, int, const char* [], int); - -void runSolver (const FactorGraph&, const VarIds&); - -const string USAGE = "usage: ./hcli [HORUS_FLAG=VALUE] \ -MODEL_FILE [VARIABLE | OBSERVED_VARIABLE=EVIDENCE] ..." ; - - -int -main (int argc, const char* argv[]) -{ - if (argc <= 1) { - cerr << "Error: no probabilistic graphical model was given." << endl; - cerr << USAGE << endl; - exit (EXIT_FAILURE); - } - int idx = readHorusFlags (argc, argv); - FactorGraph fg; - readFactorGraph (fg, argv[idx]); - VarIds queryIds = readQueryAndEvidence (fg, argc, argv, idx + 1); - runSolver (fg, queryIds); - return 0; -} - - - -int -readHorusFlags (int argc, const char* argv[]) -{ - int i = 1; - for (; i < argc; i++) { - const string& arg = argv[i]; - size_t pos = arg.find ('='); - if (pos == std::string::npos) { - return i; - } - string leftArg = arg.substr (0, pos); - string rightArg = arg.substr (pos + 1); - if (leftArg.empty()) { - cerr << "Error: missing left argument." << endl; - cerr << USAGE << endl; - exit (EXIT_FAILURE); - } - if (rightArg.empty()) { - cerr << "Error: missing right argument." << endl; - cerr << USAGE << endl; - exit (EXIT_FAILURE); - } - Util::setHorusFlag (leftArg, rightArg); - } - return i + 1; -} - - - -void -readFactorGraph (FactorGraph& fg, const char* s) -{ - string fileName (s); - string extension = fileName.substr (fileName.find_last_of ('.') + 1); - if (extension == "uai") { - fg.readFromUaiFormat (fileName.c_str()); - } else if (extension == "fg") { - fg.readFromLibDaiFormat (fileName.c_str()); - } else { - cerr << "Error: the probabilistic graphical model must be " ; - cerr << "defined either in a UAI or libDAI file." << endl; - exit (EXIT_FAILURE); - } -} - - - -VarIds -readQueryAndEvidence ( - FactorGraph& fg, - int argc, - const char* argv[], - int start) -{ - VarIds queryIds; - for (int i = start; i < argc; i++) { - const string& arg = argv[i]; - if (arg.find ('=') == std::string::npos) { - if (Util::isInteger (arg) == false) { - cerr << "Error: `" << arg << "' " ; - cerr << "is not a variable id." ; - cerr << endl; - exit (EXIT_FAILURE); - } - VarId vid = Util::stringToUnsigned (arg); - VarNode* queryVar = fg.getVarNode (vid); - if (queryVar == false) { - cerr << "Error: unknow variable with id " ; - cerr << "`" << vid << "'." << endl; - exit (EXIT_FAILURE); - } - queryIds.push_back (vid); - } else { - size_t pos = arg.find ('='); - string leftArg = arg.substr (0, pos); - string rightArg = arg.substr (pos + 1); - if (leftArg.empty()) { - cerr << "Error: missing left argument." << endl; - cerr << USAGE << endl; - exit (EXIT_FAILURE); - } - if (Util::isInteger (leftArg) == false) { - cerr << "Error: `" << leftArg << "' " ; - cerr << "is not a variable id." << endl ; - exit (EXIT_FAILURE); - } - VarId vid = Util::stringToUnsigned (leftArg); - VarNode* observedVar = fg.getVarNode (vid); - if (observedVar == false) { - cerr << "Error: unknow variable with id " ; - cerr << "`" << vid << "'." << endl; - exit (EXIT_FAILURE); - } - if (rightArg.empty()) { - cerr << "Error: missing right argument." << endl; - cerr << USAGE << endl; - exit (EXIT_FAILURE); - } - if (Util::isInteger (rightArg) == false) { - cerr << "Error: `" << rightArg << "' " ; - cerr << "is not a state index." << endl ; - exit (EXIT_FAILURE); - } - unsigned stateIdx = Util::stringToUnsigned (rightArg); - if (observedVar->isValidState (stateIdx) == false) { - cerr << "Error: `" << stateIdx << "' " ; - cerr << "is not a valid state index for variable with id " ; - cerr << "`" << vid << "'." << endl; - exit (EXIT_FAILURE); - } - observedVar->setEvidence (stateIdx); - } - } - return queryIds; -} - - - -void -runSolver (const FactorGraph& fg, const VarIds& queryIds) -{ - GroundSolver* solver = 0; - switch (Globals::groundSolver) { - case GroundSolverType::VE: - solver = new VarElim (fg); - break; - case GroundSolverType::BP: - solver = new BeliefProp (fg); - break; - case GroundSolverType::CBP: - solver = new CountingBp (fg); - break; - default: - assert (false); - } - if (Globals::verbosity > 0) { - solver->printSolverFlags(); - cout << endl; - } - if (queryIds.empty()) { - solver->printAllPosterioris(); - } else { - solver->printAnswer (queryIds); - } - delete solver; -} - diff --git a/packages/CLPBN/horus2/HorusYap.cpp b/packages/CLPBN/horus2/HorusYap.cpp deleted file mode 100644 index 3c566b73a..000000000 --- a/packages/CLPBN/horus2/HorusYap.cpp +++ /dev/null @@ -1,570 +0,0 @@ -#include - -#include - -#include -#include - -#include - -#include "ParfactorList.h" -#include "FactorGraph.h" -#include "LiftedOperations.h" -#include "LiftedVe.h" -#include "VarElim.h" -#include "LiftedBp.h" -#include "CountingBp.h" -#include "BeliefProp.h" -#include "LiftedKc.h" -#include "ElimGraph.h" -#include "BayesBall.h" - - -using namespace std; - -typedef std::pair LiftedNetwork; - -Parfactor* readParfactor (YAP_Term); - -void readLiftedEvidence (YAP_Term, ObservedFormulas&); - -vector readUnsignedList (YAP_Term list); - -Params readParameters (YAP_Term); - -YAP_Term fillAnswersPrologList (vector& results); - - - -int -createLiftedNetwork (void) -{ - Parfactors parfactors; - YAP_Term parfactorList = YAP_ARG1; - while (parfactorList != YAP_TermNil()) { - YAP_Term pfTerm = YAP_HeadOfTerm (parfactorList); - parfactors.push_back (readParfactor (pfTerm)); - parfactorList = YAP_TailOfTerm (parfactorList); - } - - // LiftedUtils::printSymbolDictionary(); - if (Globals::verbosity > 2) { - Util::printHeader ("INITIAL PARFACTORS"); - for (size_t i = 0; i < parfactors.size(); i++) { - parfactors[i]->print(); - cout << endl; - } - } - - ParfactorList* pfList = new ParfactorList (parfactors); - - if (Globals::verbosity > 2) { - Util::printHeader ("SHATTERED PARFACTORS"); - pfList->print(); - } - - // read evidence - ObservedFormulas* obsFormulas = new ObservedFormulas(); - readLiftedEvidence (YAP_ARG2, *(obsFormulas)); - - LiftedNetwork* net = new LiftedNetwork (pfList, obsFormulas); - - YAP_Int p = (YAP_Int) (net); - return YAP_Unify (YAP_MkIntTerm (p), YAP_ARG3); -} - - - -int -createGroundNetwork (void) -{ - string factorsType ((char*) YAP_AtomName (YAP_AtomOfTerm (YAP_ARG1))); - FactorGraph* fg = new FactorGraph(); - if (factorsType == "bayes") { - fg->setFactorsAsBayesian(); - } - YAP_Term factorList = YAP_ARG2; - while (factorList != YAP_TermNil()) { - YAP_Term factor = YAP_HeadOfTerm (factorList); - // read the var ids - VarIds varIds = readUnsignedList (YAP_ArgOfTerm (1, factor)); - // read the ranges - Ranges ranges = readUnsignedList (YAP_ArgOfTerm (2, factor)); - // read the parameters - Params params = readParameters (YAP_ArgOfTerm (3, factor)); - // read dist id - unsigned distId = (unsigned) YAP_IntOfTerm (YAP_ArgOfTerm (4, factor)); - fg->addFactor (Factor (varIds, ranges, params, distId)); - factorList = YAP_TailOfTerm (factorList); - } - unsigned nrObservedVars = 0; - YAP_Term evidenceList = YAP_ARG3; - while (evidenceList != YAP_TermNil()) { - YAP_Term evTerm = YAP_HeadOfTerm (evidenceList); - unsigned vid = (unsigned) YAP_IntOfTerm ((YAP_ArgOfTerm (1, evTerm))); - unsigned ev = (unsigned) YAP_IntOfTerm ((YAP_ArgOfTerm (2, evTerm))); - assert (fg->getVarNode (vid)); - fg->getVarNode (vid)->setEvidence (ev); - evidenceList = YAP_TailOfTerm (evidenceList); - nrObservedVars ++; - } - if (Globals::verbosity > 0) { - cout << "factor graph contains " ; - cout << fg->nrVarNodes() << " variables " ; - cout << "(" << nrObservedVars << " observed) and " ; - cout << fg->nrFacNodes() << " factors " << endl; - } - YAP_Int p = (YAP_Int) (fg); - return YAP_Unify (YAP_MkIntTerm (p), YAP_ARG4); -} - - - -int -runLiftedSolver (void) -{ - LiftedNetwork* network = (LiftedNetwork*) YAP_IntOfTerm (YAP_ARG1); - ParfactorList pfListCopy (*network->first); - LiftedOperations::absorveEvidence (pfListCopy, *network->second); - - LiftedSolver* solver = 0; - switch (Globals::liftedSolver) { - case LiftedSolverType::LVE: solver = new LiftedVe (pfListCopy); break; - case LiftedSolverType::LBP: solver = new LiftedBp (pfListCopy); break; - case LiftedSolverType::LKC: solver = new LiftedKc (pfListCopy); break; - } - - if (Globals::verbosity > 0) { - solver->printSolverFlags(); - cout << endl; - } - - YAP_Term taskList = YAP_ARG2; - vector results; - while (taskList != YAP_TermNil()) { - Grounds queryVars; - YAP_Term jointList = YAP_HeadOfTerm (taskList); - while (jointList != YAP_TermNil()) { - YAP_Term ground = YAP_HeadOfTerm (jointList); - if (YAP_IsAtomTerm (ground)) { - string name ((char*) YAP_AtomName (YAP_AtomOfTerm (ground))); - queryVars.push_back (Ground (LiftedUtils::getSymbol (name))); - } else { - assert (YAP_IsApplTerm (ground)); - YAP_Functor yapFunctor = YAP_FunctorOfTerm (ground); - string name ((char*) (YAP_AtomName (YAP_NameOfFunctor (yapFunctor)))); - unsigned arity = (unsigned) YAP_ArityOfFunctor (yapFunctor); - Symbol functor = LiftedUtils::getSymbol (name); - Symbols args; - for (unsigned i = 1; i <= arity; i++) { - YAP_Term ti = YAP_ArgOfTerm (i, ground); - assert (YAP_IsAtomTerm (ti)); - string arg ((char *) YAP_AtomName (YAP_AtomOfTerm (ti))); - args.push_back (LiftedUtils::getSymbol (arg)); - } - queryVars.push_back (Ground (functor, args)); - } - jointList = YAP_TailOfTerm (jointList); - } - results.push_back (solver->solveQuery (queryVars)); - taskList = YAP_TailOfTerm (taskList); - } - - delete solver; - - return YAP_Unify (fillAnswersPrologList (results), YAP_ARG3); -} - - - -int -runGroundSolver (void) -{ - FactorGraph* fg = (FactorGraph*) YAP_IntOfTerm (YAP_ARG1); - - vector tasks; - YAP_Term taskList = YAP_ARG2; - while (taskList != YAP_TermNil()) { - tasks.push_back (readUnsignedList (YAP_HeadOfTerm (taskList))); - taskList = YAP_TailOfTerm (taskList); - } - - FactorGraph* mfg = fg; - if (fg->bayesianFactors()) { - std::set vids; - for (size_t i = 0; i < tasks.size(); i++) { - Util::addToSet (vids, tasks[i]); - } - mfg = BayesBall::getMinimalFactorGraph ( - *fg, VarIds (vids.begin(), vids.end())); - } - - GroundSolver* solver = 0; - CountingBp::checkForIdenticalFactors = false; - switch (Globals::groundSolver) { - case GroundSolverType::VE: solver = new VarElim (*mfg); break; - case GroundSolverType::BP: solver = new BeliefProp (*mfg); break; - case GroundSolverType::CBP: solver = new CountingBp (*mfg); break; - } - - if (Globals::verbosity > 0) { - solver->printSolverFlags(); - cout << endl; - } - - vector results; - results.reserve (tasks.size()); - for (size_t i = 0; i < tasks.size(); i++) { - results.push_back (solver->solveQuery (tasks[i])); - } - - delete solver; - if (fg->bayesianFactors()) { - delete mfg; - } - - return YAP_Unify (fillAnswersPrologList (results), YAP_ARG3); -} - - - -int -setParfactorsParams (void) -{ - LiftedNetwork* network = (LiftedNetwork*) YAP_IntOfTerm (YAP_ARG1); - ParfactorList* pfList = network->first; - YAP_Term distIdsList = YAP_ARG2; - YAP_Term paramsList = YAP_ARG3; - unordered_map paramsMap; - while (distIdsList != YAP_TermNil()) { - unsigned distId = (unsigned) YAP_IntOfTerm ( - YAP_HeadOfTerm (distIdsList)); - assert (Util::contains (paramsMap, distId) == false); - paramsMap[distId] = readParameters (YAP_HeadOfTerm (paramsList)); - distIdsList = YAP_TailOfTerm (distIdsList); - paramsList = YAP_TailOfTerm (paramsList); - } - ParfactorList::iterator it = pfList->begin(); - while (it != pfList->end()) { - assert (Util::contains (paramsMap, (*it)->distId())); - (*it)->setParams (paramsMap[(*it)->distId()]); - ++ it; - } - return TRUE; -} - - - -int -setFactorsParams (void) -{ - FactorGraph* fg = (FactorGraph*) YAP_IntOfTerm (YAP_ARG1); - YAP_Term distIdsList = YAP_ARG2; - YAP_Term paramsList = YAP_ARG3; - unordered_map paramsMap; - while (distIdsList != YAP_TermNil()) { - unsigned distId = (unsigned) YAP_IntOfTerm ( - YAP_HeadOfTerm (distIdsList)); - assert (Util::contains (paramsMap, distId) == false); - paramsMap[distId] = readParameters (YAP_HeadOfTerm (paramsList)); - distIdsList = YAP_TailOfTerm (distIdsList); - paramsList = YAP_TailOfTerm (paramsList); - } - const FacNodes& facNodes = fg->facNodes(); - for (size_t i = 0; i < facNodes.size(); i++) { - unsigned distId = facNodes[i]->factor().distId(); - assert (Util::contains (paramsMap, distId)); - facNodes[i]->factor().setParams (paramsMap[distId]); - } - return TRUE; -} - - - -int -setVarsInformation (void) -{ - Var::clearVarsInfo(); - vector labels; - YAP_Term labelsL = YAP_ARG1; - while (labelsL != YAP_TermNil()) { - YAP_Atom atom = YAP_AtomOfTerm (YAP_HeadOfTerm (labelsL)); - labels.push_back ((char*) YAP_AtomName (atom)); - labelsL = YAP_TailOfTerm (labelsL); - } - unsigned count = 0; - YAP_Term stateNamesL = YAP_ARG2; - while (stateNamesL != YAP_TermNil()) { - States states; - YAP_Term namesL = YAP_HeadOfTerm (stateNamesL); - while (namesL != YAP_TermNil()) { - YAP_Atom atom = YAP_AtomOfTerm (YAP_HeadOfTerm (namesL)); - states.push_back ((char*) YAP_AtomName (atom)); - namesL = YAP_TailOfTerm (namesL); - } - Var::addVarInfo (count, labels[count], states); - count ++; - stateNamesL = YAP_TailOfTerm (stateNamesL); - } - return TRUE; -} - - - -int -setHorusFlag (void) -{ - string key ((char*) YAP_AtomName (YAP_AtomOfTerm (YAP_ARG1))); - string value; - if (key == "verbosity") { - stringstream ss; - ss << (int) YAP_IntOfTerm (YAP_ARG2); - ss >> value; - } else if (key == "accuracy") { - stringstream ss; - ss << (float) YAP_FloatOfTerm (YAP_ARG2); - ss >> value; - } else if (key == "max_iter") { - stringstream ss; - ss << (int) YAP_IntOfTerm (YAP_ARG2); - ss >> value; - } else { - value = ((char*) YAP_AtomName (YAP_AtomOfTerm (YAP_ARG2))); - } - return Util::setHorusFlag (key, value); -} - - - -int -freeGroundNetwork (void) -{ - delete (FactorGraph*) YAP_IntOfTerm (YAP_ARG1); - return TRUE; -} - - - -int -freeLiftedNetwork (void) -{ - LiftedNetwork* network = (LiftedNetwork*) YAP_IntOfTerm (YAP_ARG1); - delete network->first; - delete network->second; - delete network; - return TRUE; -} - - - -Parfactor* -readParfactor (YAP_Term pfTerm) -{ - // read dist id - unsigned distId = YAP_IntOfTerm (YAP_ArgOfTerm (1, pfTerm)); - - // read the ranges - Ranges ranges; - YAP_Term rangeList = YAP_ArgOfTerm (3, pfTerm); - while (rangeList != YAP_TermNil()) { - unsigned range = (unsigned) YAP_IntOfTerm (YAP_HeadOfTerm (rangeList)); - ranges.push_back (range); - rangeList = YAP_TailOfTerm (rangeList); - } - - // read parametric random vars - ProbFormulas formulas; - unsigned count = 0; - unordered_map lvMap; - YAP_Term pvList = YAP_ArgOfTerm (2, pfTerm); - while (pvList != YAP_TermNil()) { - YAP_Term formulaTerm = YAP_HeadOfTerm (pvList); - if (YAP_IsAtomTerm (formulaTerm)) { - string name ((char*) YAP_AtomName (YAP_AtomOfTerm (formulaTerm))); - Symbol functor = LiftedUtils::getSymbol (name); - formulas.push_back (ProbFormula (functor, ranges[count])); - } else { - LogVars logVars; - YAP_Functor yapFunctor = YAP_FunctorOfTerm (formulaTerm); - string name ((char*) YAP_AtomName (YAP_NameOfFunctor (yapFunctor))); - Symbol functor = LiftedUtils::getSymbol (name); - unsigned arity = (unsigned) YAP_ArityOfFunctor (yapFunctor); - for (unsigned i = 1; i <= arity; i++) { - YAP_Term ti = YAP_ArgOfTerm (i, formulaTerm); - unordered_map::iterator it = lvMap.find (ti); - if (it != lvMap.end()) { - logVars.push_back (it->second); - } else { - unsigned newLv = lvMap.size(); - lvMap[ti] = newLv; - logVars.push_back (newLv); - } - } - formulas.push_back (ProbFormula (functor, logVars, ranges[count])); - } - count ++; - pvList = YAP_TailOfTerm (pvList); - } - - // read the parameters - const Params& params = readParameters (YAP_ArgOfTerm (4, pfTerm)); - - // read the constraint - Tuples tuples; - if (lvMap.size() >= 1) { - YAP_Term tupleList = YAP_ArgOfTerm (5, pfTerm); - while (tupleList != YAP_TermNil()) { - YAP_Term term = YAP_HeadOfTerm (tupleList); - assert (YAP_IsApplTerm (term)); - YAP_Functor yapFunctor = YAP_FunctorOfTerm (term); - unsigned arity = (unsigned) YAP_ArityOfFunctor (yapFunctor); - assert (lvMap.size() == arity); - Tuple tuple (arity); - for (unsigned i = 1; i <= arity; i++) { - YAP_Term ti = YAP_ArgOfTerm (i, term); - if (YAP_IsAtomTerm (ti) == false) { - cerr << "Error: the constraint contains free variables." << endl; - exit (EXIT_FAILURE); - } - string name ((char*) YAP_AtomName (YAP_AtomOfTerm (ti))); - tuple[i - 1] = LiftedUtils::getSymbol (name); - } - tuples.push_back (tuple); - tupleList = YAP_TailOfTerm (tupleList); - } - } - return new Parfactor (formulas, params, tuples, distId); -} - - - -void -readLiftedEvidence ( - YAP_Term observedList, - ObservedFormulas& obsFormulas) -{ - while (observedList != YAP_TermNil()) { - YAP_Term pair = YAP_HeadOfTerm (observedList); - YAP_Term ground = YAP_ArgOfTerm (1, pair); - Symbol functor; - Symbols args; - if (YAP_IsAtomTerm (ground)) { - string name ((char*) YAP_AtomName (YAP_AtomOfTerm (ground))); - functor = LiftedUtils::getSymbol (name); - } else { - assert (YAP_IsApplTerm (ground)); - YAP_Functor yapFunctor = YAP_FunctorOfTerm (ground); - string name ((char*) (YAP_AtomName (YAP_NameOfFunctor (yapFunctor)))); - functor = LiftedUtils::getSymbol (name); - unsigned arity = (unsigned) YAP_ArityOfFunctor (yapFunctor); - for (unsigned i = 1; i <= arity; i++) { - YAP_Term ti = YAP_ArgOfTerm (i, ground); - assert (YAP_IsAtomTerm (ti)); - string arg ((char *) YAP_AtomName (YAP_AtomOfTerm (ti))); - args.push_back (LiftedUtils::getSymbol (arg)); - } - } - unsigned evidence = (unsigned) YAP_IntOfTerm (YAP_ArgOfTerm (2, pair)); - bool found = false; - for (size_t i = 0; i < obsFormulas.size(); i++) { - if (obsFormulas[i].functor() == functor && - obsFormulas[i].arity() == args.size() && - obsFormulas[i].evidence() == evidence) { - obsFormulas[i].addTuple (args); - found = true; - } - } - if (found == false) { - obsFormulas.push_back (ObservedFormula (functor, evidence, args)); - } - observedList = YAP_TailOfTerm (observedList); - } -} - - - -vector -readUnsignedList (YAP_Term list) -{ - vector vec; - while (list != YAP_TermNil()) { - vec.push_back ((unsigned) YAP_IntOfTerm (YAP_HeadOfTerm (list))); - list = YAP_TailOfTerm (list); - } - return vec; -} - - - -Params -readParameters (YAP_Term paramL) -{ - Params params; - assert (YAP_IsPairTerm (paramL)); - while (paramL != YAP_TermNil()) { - params.push_back ((double) YAP_FloatOfTerm (YAP_HeadOfTerm (paramL))); - paramL = YAP_TailOfTerm (paramL); - } - if (Globals::logDomain) { - Util::log (params); - } - return params; -} - - - -YAP_Term -fillAnswersPrologList (vector& results) -{ - YAP_Term list = YAP_TermNil(); - for (size_t i = results.size(); i-- > 0; ) { - const Params& beliefs = results[i]; - YAP_Term queryBeliefsL = YAP_TermNil(); - for (size_t j = beliefs.size(); j-- > 0; ) { - YAP_Int sl1 = YAP_InitSlot (list); - YAP_Term belief = YAP_MkFloatTerm (beliefs[j]); - queryBeliefsL = YAP_MkPairTerm (belief, queryBeliefsL); - list = YAP_GetFromSlot (sl1); - YAP_RecoverSlots (1); - } - list = YAP_MkPairTerm (queryBeliefsL, list); - } - return list; -} - - - -extern "C" void -init_predicates (void) -{ - YAP_UserCPredicate ("cpp_create_lifted_network", - createLiftedNetwork, 3); - - YAP_UserCPredicate ("cpp_create_ground_network", - createGroundNetwork, 4); - - YAP_UserCPredicate ("cpp_run_lifted_solver", - runLiftedSolver, 3); - - YAP_UserCPredicate ("cpp_run_ground_solver", - runGroundSolver, 3); - - YAP_UserCPredicate ("cpp_set_parfactors_params", - setParfactorsParams, 3); - - YAP_UserCPredicate ("cpp_set_factors_params", - setFactorsParams, 3); - - YAP_UserCPredicate ("cpp_set_vars_information", - setVarsInformation, 2); - - YAP_UserCPredicate ("cpp_set_horus_flag", - setHorusFlag, 2); - - YAP_UserCPredicate ("cpp_free_lifted_network", - freeLiftedNetwork, 1); - - YAP_UserCPredicate ("cpp_free_ground_network", - freeGroundNetwork, 1); -} - diff --git a/packages/CLPBN/horus2/Indexer.h b/packages/CLPBN/horus2/Indexer.h deleted file mode 100644 index db99cf1a7..000000000 --- a/packages/CLPBN/horus2/Indexer.h +++ /dev/null @@ -1,258 +0,0 @@ -#ifndef HORUS_INDEXER_H -#define HORUS_INDEXER_H - -#include -#include - -#include -#include - -#include "Util.h" - - -class Indexer -{ - public: - Indexer (const Ranges& ranges, bool calcOffsets = true) - : index_(0), indices_(ranges.size(), 0), ranges_(ranges), - size_(Util::sizeExpected (ranges)) - { - if (calcOffsets) { - calculateOffsets(); - } - } - - void increment (void) - { - for (size_t i = ranges_.size(); i-- > 0; ) { - indices_[i] ++; - if (indices_[i] != ranges_[i]) { - break; - } else { - indices_[i] = 0; - } - } - index_ ++; - } - - void incrementDimension (size_t dim) - { - assert (dim < ranges_.size()); - assert (ranges_.size() == offsets_.size()); - assert (indices_[dim] < ranges_[dim]); - indices_[dim] ++; - index_ += offsets_[dim]; - } - - void incrementExceptDimension (size_t dim) - { - assert (ranges_.size() == offsets_.size()); - for (size_t i = ranges_.size(); i-- > 0; ) { - if (i != dim) { - indices_[i] ++; - index_ += offsets_[i]; - if (indices_[i] != ranges_[i]) { - return; - } else { - indices_[i] = 0; - index_ -= offsets_[i] * ranges_[i]; - } - } - } - index_ = size_; - } - - Indexer& operator++ (void) - { - increment(); - return *this; - } - - operator size_t (void) const - { - return index_; - } - - unsigned operator[] (size_t dim) const - { - assert (valid()); - assert (dim < ranges_.size()); - return indices_[dim]; - } - - bool valid (void) const - { - return index_ < size_; - } - - void reset (void) - { - std::fill (indices_.begin(), indices_.end(), 0); - index_ = 0; - } - - void resetDimension (size_t dim) - { - indices_[dim] = 0; - index_ -= offsets_[dim] * ranges_[dim]; - } - - size_t size (void) const - { - return size_ ; - } - - friend std::ostream& operator<< (std::ostream&, const Indexer&); - - private: - void calculateOffsets (void) - { - size_t prod = 1; - offsets_.resize (ranges_.size()); - for (size_t i = ranges_.size(); i-- > 0; ) { - offsets_[i] = prod; - prod *= ranges_[i]; - } - } - - size_t index_; - Ranges indices_; - const Ranges& ranges_; - size_t size_; - vector offsets_; -}; - - - -inline std::ostream& -operator<< (std::ostream& os, const Indexer& indexer) -{ - os << "(" ; - os << std::setw (2) << std::setfill('0') << indexer.index_; - os << ") " ; - os << indexer.indices_; - return os; -} - - - -class MapIndexer -{ - public: - MapIndexer (const Ranges& ranges, const vector& mask) - : index_(0), indices_(ranges.size(), 0), ranges_(ranges), - valid_(true) - { - size_t prod = 1; - offsets_.resize (ranges.size(), 0); - for (size_t i = ranges.size(); i-- > 0; ) { - if (mask[i]) { - offsets_[i] = prod; - prod *= ranges[i]; - } - } - assert (ranges.size() == mask.size()); - } - - MapIndexer (const Ranges& ranges, size_t dim) - : index_(0), indices_(ranges.size(), 0), ranges_(ranges), - valid_(true) - { - size_t prod = 1; - offsets_.resize (ranges.size(), 0); - for (size_t i = ranges.size(); i-- > 0; ) { - if (i != dim) { - offsets_[i] = prod; - prod *= ranges[i]; - } - } - } - - template - MapIndexer ( - const vector& allArgs, - const Ranges& allRanges, - const vector& wantedArgs, - const Ranges& wantedRanges) - : index_(0), indices_(allArgs.size(), 0), ranges_(allRanges), - valid_(true) - { - size_t prod = 1; - vector offsets (wantedRanges.size()); - for (size_t i = wantedRanges.size(); i-- > 0; ) { - offsets[i] = prod; - prod *= wantedRanges[i]; - } - offsets_.reserve (allArgs.size()); - for (size_t i = 0; i < allArgs.size(); i++) { - size_t idx = Util::indexOf (wantedArgs, allArgs[i]); - offsets_.push_back (idx != wantedArgs.size() ? offsets[idx] : 0); - } - } - - MapIndexer& operator++ (void) - { - assert (valid_); - for (size_t i = ranges_.size(); i-- > 0; ) { - indices_[i] ++; - index_ += offsets_[i]; - if (indices_[i] != ranges_[i]) { - return *this; - } else { - indices_[i] = 0; - index_ -= offsets_[i] * ranges_[i]; - } - } - valid_ = false; - return *this; - } - - operator size_t (void) const - { - assert (valid()); - return index_; - } - - unsigned operator[] (size_t dim) const - { - assert (valid()); - assert (dim < ranges_.size()); - return indices_[dim]; - } - - bool valid (void) const - { - return valid_; - } - - void reset (void) - { - std::fill (indices_.begin(), indices_.end(), 0); - index_ = 0; - } - - friend std::ostream& operator<< (std::ostream&, const MapIndexer&); - - private: - size_t index_; - Ranges indices_; - const Ranges& ranges_; - bool valid_; - vector offsets_; -}; - - - -inline std::ostream& -operator<< (std::ostream &os, const MapIndexer& indexer) -{ - os << "(" ; - os << std::setw (2) << std::setfill('0') << indexer.index_; - os << ") " ; - os << indexer.indices_; - return os; -} - - -#endif // HORUS_INDEXER_H - diff --git a/packages/CLPBN/horus2/LiftedBp.cpp b/packages/CLPBN/horus2/LiftedBp.cpp deleted file mode 100644 index d3f757704..000000000 --- a/packages/CLPBN/horus2/LiftedBp.cpp +++ /dev/null @@ -1,234 +0,0 @@ -#include "LiftedBp.h" -#include "WeightedBp.h" -#include "FactorGraph.h" -#include "LiftedOperations.h" - - -LiftedBp::LiftedBp (const ParfactorList& parfactorList) - : LiftedSolver (parfactorList) -{ - refineParfactors(); - createFactorGraph(); - solver_ = new WeightedBp (*fg_, getWeights()); -} - - - -LiftedBp::~LiftedBp (void) -{ - delete solver_; - delete fg_; -} - - - -Params -LiftedBp::solveQuery (const Grounds& query) -{ - assert (query.empty() == false); - Params res; - vector groups = getQueryGroups (query); - if (query.size() == 1) { - res = solver_->getPosterioriOf (groups[0]); - } else { - ParfactorList::iterator it = pfList_.begin(); - size_t idx = pfList_.size(); - size_t count = 0; - while (it != pfList_.end()) { - if ((*it)->containsGrounds (query)) { - idx = count; - break; - } - ++ it; - ++ count; - } - if (idx == pfList_.size()) { - res = getJointByConditioning (pfList_, query); - } else { - VarIds queryVids; - for (unsigned i = 0; i < groups.size(); i++) { - queryVids.push_back (groups[i]); - } - res = solver_->getFactorJoint (fg_->facNodes()[idx], queryVids); - } - } - return res; -} - - - -void -LiftedBp::printSolverFlags (void) const -{ - stringstream ss; - ss << "lifted bp [" ; - ss << "schedule=" ; - typedef BpOptions::Schedule Sch; - switch (BpOptions::schedule) { - case Sch::SEQ_FIXED: ss << "seq_fixed"; break; - case Sch::SEQ_RANDOM: ss << "seq_random"; break; - case Sch::PARALLEL: ss << "parallel"; break; - case Sch::MAX_RESIDUAL: ss << "max_residual"; break; - } - ss << ",max_iter=" << BpOptions::maxIter; - ss << ",accuracy=" << BpOptions::accuracy; - ss << ",log_domain=" << Util::toString (Globals::logDomain); - ss << "]" ; - cout << ss.str() << endl; -} - - - -void -LiftedBp::refineParfactors (void) -{ - pfList_ = parfactorList; - while (iterate() == false); - - if (Globals::verbosity > 2) { - Util::printHeader ("AFTER REFINEMENT"); - pfList_.print(); - } -} - - - -bool -LiftedBp::iterate (void) -{ - ParfactorList::iterator it = pfList_.begin(); - while (it != pfList_.end()) { - const ProbFormulas& args = (*it)->arguments(); - for (size_t i = 0; i < args.size(); i++) { - LogVarSet lvs = (*it)->logVarSet() - args[i].logVars(); - if ((*it)->constr()->isCountNormalized (lvs) == false) { - Parfactors pfs = LiftedOperations::countNormalize (*it, lvs); - it = pfList_.removeAndDelete (it); - pfList_.add (pfs); - return false; - } - } - ++ it; - } - return true; -} - - - -vector -LiftedBp::getQueryGroups (const Grounds& query) -{ - vector queryGroups; - for (unsigned i = 0; i < query.size(); i++) { - ParfactorList::const_iterator it = pfList_.begin(); - for (; it != pfList_.end(); ++it) { - if ((*it)->containsGround (query[i])) { - queryGroups.push_back ((*it)->findGroup (query[i])); - break; - } - } - } - assert (queryGroups.size() == query.size()); - return queryGroups; -} - - - -void -LiftedBp::createFactorGraph (void) -{ - fg_ = new FactorGraph(); - ParfactorList::const_iterator it = pfList_.begin(); - for (; it != pfList_.end(); ++it) { - vector groups = (*it)->getAllGroups(); - VarIds varIds; - for (size_t i = 0; i < groups.size(); i++) { - varIds.push_back (groups[i]); - } - fg_->addFactor (Factor (varIds, (*it)->ranges(), (*it)->params())); - } -} - - - -vector> -LiftedBp::getWeights (void) const -{ - vector> weights; - weights.reserve (pfList_.size()); - ParfactorList::const_iterator it = pfList_.begin(); - for (; it != pfList_.end(); ++it) { - const ProbFormulas& args = (*it)->arguments(); - weights.push_back ({ }); - weights.back().reserve (args.size()); - for (size_t i = 0; i < args.size(); i++) { - LogVarSet lvs = (*it)->logVarSet() - args[i].logVars(); - weights.back().push_back ((*it)->constr()->getConditionalCount (lvs)); - } - } - return weights; -} - - - -unsigned -LiftedBp::rangeOfGround (const Ground& gr) -{ - ParfactorList::iterator it = pfList_.begin(); - while (it != pfList_.end()) { - if ((*it)->containsGround (gr)) { - PrvGroup prvGroup = (*it)->findGroup (gr); - return (*it)->range ((*it)->indexOfGroup (prvGroup)); - } - ++ it; - } - return std::numeric_limits::max(); -} - - - -Params -LiftedBp::getJointByConditioning ( - const ParfactorList& pfList, - const Grounds& query) -{ - LiftedBp solver (pfList); - Params prevBeliefs = solver.solveQuery ({query[0]}); - Grounds obsGrounds = {query[0]}; - for (size_t i = 1; i < query.size(); i++) { - Params newBeliefs; - vector obsFs; - Ranges obsRanges; - for (size_t j = 0; j < obsGrounds.size(); j++) { - obsFs.push_back (ObservedFormula ( - obsGrounds[j].functor(), 0, obsGrounds[j].args())); - obsRanges.push_back (rangeOfGround (obsGrounds[j])); - } - Indexer indexer (obsRanges, false); - while (indexer.valid()) { - for (size_t j = 0; j < obsFs.size(); j++) { - obsFs[j].setEvidence (indexer[j]); - } - ParfactorList tempPfList (pfList); - LiftedOperations::absorveEvidence (tempPfList, obsFs); - LiftedBp solver (tempPfList); - Params beliefs = solver.solveQuery ({query[i]}); - for (size_t k = 0; k < beliefs.size(); k++) { - newBeliefs.push_back (beliefs[k]); - } - ++ indexer; - } - int count = -1; - unsigned range = rangeOfGround (query[i]); - for (size_t j = 0; j < newBeliefs.size(); j++) { - if (j % range == 0) { - count ++; - } - newBeliefs[j] *= prevBeliefs[count]; - } - prevBeliefs = newBeliefs; - obsGrounds.push_back (query[i]); - } - return prevBeliefs; -} - diff --git a/packages/CLPBN/horus2/LiftedBp.h b/packages/CLPBN/horus2/LiftedBp.h deleted file mode 100644 index 274503f29..000000000 --- a/packages/CLPBN/horus2/LiftedBp.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef HORUS_LIFTEDBP_H -#define HORUS_LIFTEDBP_H - -#include "LiftedSolver.h" -#include "ParfactorList.h" - -class FactorGraph; -class WeightedBp; - -class LiftedBp : public LiftedSolver -{ - public: - LiftedBp (const ParfactorList& pfList); - - ~LiftedBp (void); - - Params solveQuery (const Grounds&); - - void printSolverFlags (void) const; - - private: - void refineParfactors (void); - - bool iterate (void); - - vector getQueryGroups (const Grounds&); - - void createFactorGraph (void); - - vector> getWeights (void) const; - - unsigned rangeOfGround (const Ground&); - - Params getJointByConditioning (const ParfactorList&, const Grounds&); - - ParfactorList pfList_; - WeightedBp* solver_; - FactorGraph* fg_; - -}; - -#endif // HORUS_LIFTEDBP_H - diff --git a/packages/CLPBN/horus2/LiftedKc.cpp b/packages/CLPBN/horus2/LiftedKc.cpp deleted file mode 100644 index 45848ab70..000000000 --- a/packages/CLPBN/horus2/LiftedKc.cpp +++ /dev/null @@ -1,1309 +0,0 @@ -#include - -#include "LiftedKc.h" -#include "LiftedOperations.h" -#include "Indexer.h" - - - -OrNode::~OrNode (void) -{ - delete leftBranch_; - delete rightBranch_; -} - - - -double -OrNode::weight (void) const -{ - double lw = leftBranch_->weight(); - double rw = rightBranch_->weight(); - return Globals::logDomain ? Util::logSum (lw, rw) : lw + rw; -} - - - -AndNode::~AndNode (void) -{ - delete leftBranch_; - delete rightBranch_; -} - - - -double -AndNode::weight (void) const -{ - double lw = leftBranch_->weight(); - double rw = rightBranch_->weight(); - return Globals::logDomain ? lw + rw : lw * rw; -} - - - -int SetOrNode::nrPos_ = -1; -int SetOrNode::nrNeg_ = -1; - - - -SetOrNode::~SetOrNode (void) -{ - delete follow_; -} - - - -double -SetOrNode::weight (void) const -{ - double weightSum = LogAware::addIdenty(); - for (unsigned i = 0; i < nrGroundings_ + 1; i++) { - nrPos_ = nrGroundings_ - i; - nrNeg_ = i; - if (Globals::logDomain) { - double nrCombs = Util::nrCombinations (nrGroundings_, i); - double w = follow_->weight(); - weightSum = Util::logSum (weightSum, std::log (nrCombs) + w); - } else { - double w = follow_->weight(); - weightSum += Util::nrCombinations (nrGroundings_, i) * w; - } - } - nrPos_ = -1; - nrNeg_ = -1; - return weightSum; -} - - - -SetAndNode::~SetAndNode (void) -{ - delete follow_; -} - - - -double -SetAndNode::weight (void) const -{ - return LogAware::pow (follow_->weight(), nrGroundings_); -} - - - -IncExcNode::~IncExcNode (void) -{ - delete plus1Branch_; - delete plus2Branch_; - delete minusBranch_; -} - - - -double -IncExcNode::weight (void) const -{ - double w = 0.0; - if (Globals::logDomain) { - w = Util::logSum (plus1Branch_->weight(), plus2Branch_->weight()); - w = std::log (std::exp (w) - std::exp (minusBranch_->weight())); - } else { - w = plus1Branch_->weight() + plus2Branch_->weight(); - w -= minusBranch_->weight(); - } - return w; -} - - - -LeafNode::~LeafNode (void) -{ - delete clause_; -} - - - -double -LeafNode::weight (void) const -{ - assert (clause_->isUnit()); - if (clause_->posCountedLogVars().empty() == false - || clause_->negCountedLogVars().empty() == false) { - if (SetOrNode::isSet() == false) { - // return a NaN if we have a SetOrNode - // ancester that is not set. This can only - // happen when calculating the weights - // for the edge labels in graphviz - return 0.0 / 0.0; - } - } - double weight = clause_->literals()[0].isPositive() - ? lwcnf_.posWeight (clause_->literals().front().lid()) - : lwcnf_.negWeight (clause_->literals().front().lid()); - LogVarSet lvs = clause_->constr().logVarSet(); - lvs -= clause_->ipgLogVars(); - lvs -= clause_->posCountedLogVars(); - lvs -= clause_->negCountedLogVars(); - unsigned nrGroundings = 1; - if (lvs.empty() == false) { - nrGroundings = clause_->constr().projectedCopy (lvs).size(); - } - if (clause_->posCountedLogVars().empty() == false) { - nrGroundings *= std::pow (SetOrNode::nrPositives(), - clause_->nrPosCountedLogVars()); - } - if (clause_->negCountedLogVars().empty() == false) { - nrGroundings *= std::pow (SetOrNode::nrNegatives(), - clause_->nrNegCountedLogVars()); - } - return LogAware::pow (weight, nrGroundings); -} - - - -SmoothNode::~SmoothNode (void) -{ - Clause::deleteClauses (clauses_); -} - - - -double -SmoothNode::weight (void) const -{ - Clauses cs = clauses(); - double totalWeight = LogAware::multIdenty(); - for (size_t i = 0; i < cs.size(); i++) { - double posWeight = lwcnf_.posWeight (cs[i]->literals()[0].lid()); - double negWeight = lwcnf_.negWeight (cs[i]->literals()[0].lid()); - LogVarSet lvs = cs[i]->constr().logVarSet(); - lvs -= cs[i]->ipgLogVars(); - lvs -= cs[i]->posCountedLogVars(); - lvs -= cs[i]->negCountedLogVars(); - unsigned nrGroundings = 1; - if (lvs.empty() == false) { - nrGroundings = cs[i]->constr().projectedCopy (lvs).size(); - } - if (cs[i]->posCountedLogVars().empty() == false) { - nrGroundings *= std::pow (SetOrNode::nrPositives(), - cs[i]->nrPosCountedLogVars()); - } - if (cs[i]->negCountedLogVars().empty() == false) { - nrGroundings *= std::pow (SetOrNode::nrNegatives(), - cs[i]->nrNegCountedLogVars()); - } - if (Globals::logDomain) { - totalWeight += Util::logSum (posWeight, negWeight) * nrGroundings; - } else { - totalWeight *= std::pow (posWeight + negWeight, nrGroundings); - } - } - return totalWeight; -} - - - -double -TrueNode::weight (void) const -{ - return LogAware::multIdenty(); -} - - - -double -CompilationFailedNode::weight (void) const -{ - // weighted model counting in compilation - // failed nodes should give NaN - return 0.0 / 0.0; -} - - - -LiftedCircuit::LiftedCircuit (const LiftedWCNF* lwcnf) - : lwcnf_(lwcnf) -{ - root_ = 0; - compilationSucceeded_ = true; - Clauses clauses = Clause::copyClauses (lwcnf->clauses()); - compile (&root_, clauses); - if (compilationSucceeded_) { - smoothCircuit (root_); - } - if (Globals::verbosity > 1) { - if (compilationSucceeded_) { - double wmc = LogAware::exp (getWeightedModelCount()); - cout << "Weighted model count = " << wmc << endl << endl; - } - cout << "Exporting circuit to graphviz (circuit.dot)..." ; - cout << endl << endl; - exportToGraphViz ("circuit.dot"); - } -} - - - -LiftedCircuit::~LiftedCircuit (void) -{ - delete root_; - unordered_map::iterator it; - it = originClausesMap_.begin(); - while (it != originClausesMap_.end()) { - Clause::deleteClauses (it->second); - ++ it; - } -} - - - -bool -LiftedCircuit::isCompilationSucceeded (void) const -{ - return compilationSucceeded_; -} - - - -double -LiftedCircuit::getWeightedModelCount (void) const -{ - assert (compilationSucceeded_); - return root_->weight(); -} - - - -void -LiftedCircuit::exportToGraphViz (const char* fileName) -{ - ofstream out (fileName); - if (!out.is_open()) { - cerr << "Error: couldn't open file '" << fileName << "'." ; - return; - } - out << "digraph {" << endl; - out << "ranksep=1" << endl; - exportToGraphViz (root_, out); - out << "}" << endl; - out.close(); -} - - - -void -LiftedCircuit::compile ( - CircuitNode** follow, - Clauses& clauses) -{ - if (compilationSucceeded_ == false - && Globals::verbosity <= 1) { - return; - } - - if (clauses.empty()) { - *follow = new TrueNode(); - return; - } - - if (clauses.size() == 1 && clauses[0]->isUnit()) { - *follow = new LeafNode (clauses[0], *lwcnf_); - return; - } - - if (tryUnitPropagation (follow, clauses)) { - return; - } - - if (tryIndependence (follow, clauses)) { - return; - } - - if (tryShannonDecomp (follow, clauses)) { - return; - } - - if (tryInclusionExclusion (follow, clauses)) { - return; - } - - if (tryIndepPartialGrounding (follow, clauses)) { - return; - } - - if (tryAtomCounting (follow, clauses)) { - return; - } - - *follow = new CompilationFailedNode(); - if (Globals::verbosity > 1) { - originClausesMap_[*follow] = clauses; - explanationMap_[*follow] = "" ; - } - compilationSucceeded_ = false; -} - - - -bool -LiftedCircuit::tryUnitPropagation ( - CircuitNode** follow, - Clauses& clauses) -{ - if (Globals::verbosity > 1) { - backupClauses_ = Clause::copyClauses (clauses); - } - for (size_t i = 0; i < clauses.size(); i++) { - if (clauses[i]->isUnit()) { - Clauses propagClauses; - for (size_t j = 0; j < clauses.size(); j++) { - if (i != j) { - LiteralId lid = clauses[i]->literals()[0].lid(); - LogVarTypes types = clauses[i]->logVarTypes (0); - if (clauses[i]->literals()[0].isPositive()) { - if (clauses[j]->containsPositiveLiteral (lid, types) == false) { - clauses[j]->removeNegativeLiterals (lid, types); - if (clauses[j]->nrLiterals() > 0) { - propagClauses.push_back (clauses[j]); - } else { - delete clauses[j]; - } - } else { - delete clauses[j]; - } - } else if (clauses[i]->literals()[0].isNegative()) { - if (clauses[j]->containsNegativeLiteral (lid, types) == false) { - clauses[j]->removePositiveLiterals (lid, types); - if (clauses[j]->nrLiterals() > 0) { - propagClauses.push_back (clauses[j]); - } else { - delete clauses[j]; - } - } else { - delete clauses[j]; - } - } - } - } - - AndNode* andNode = new AndNode(); - if (Globals::verbosity > 1) { - originClausesMap_[andNode] = backupClauses_; - stringstream explanation; - explanation << " UP on " << clauses[i]->literals()[0]; - explanationMap_[andNode] = explanation.str(); - } - - Clauses unitClause = { clauses[i] }; - compile (andNode->leftBranch(), unitClause); - compile (andNode->rightBranch(), propagClauses); - (*follow) = andNode; - return true; - } - } - if (Globals::verbosity > 1) { - Clause::deleteClauses (backupClauses_); - } - return false; -} - - - -bool -LiftedCircuit::tryIndependence ( - CircuitNode** follow, - Clauses& clauses) -{ - if (clauses.size() == 1) { - return false; - } - if (Globals::verbosity > 1) { - backupClauses_ = Clause::copyClauses (clauses); - } - Clauses depClauses = { clauses[0] }; - Clauses indepClauses (clauses.begin() + 1, clauses.end()); - bool finish = false; - while (finish == false) { - finish = true; - for (size_t i = 0; i < indepClauses.size(); i++) { - if (independentClause (*indepClauses[i], depClauses) == false) { - depClauses.push_back (indepClauses[i]); - indepClauses.erase (indepClauses.begin() + i); - finish = false; - break; - } - } - } - if (indepClauses.empty() == false) { - AndNode* andNode = new AndNode (); - if (Globals::verbosity > 1) { - originClausesMap_[andNode] = backupClauses_; - explanationMap_[andNode] = " Independence" ; - } - compile (andNode->leftBranch(), depClauses); - compile (andNode->rightBranch(), indepClauses); - (*follow) = andNode; - return true; - } - if (Globals::verbosity > 1) { - Clause::deleteClauses (backupClauses_); - } - return false; -} - - - -bool -LiftedCircuit::tryShannonDecomp ( - CircuitNode** follow, - Clauses& clauses) -{ - if (Globals::verbosity > 1) { - backupClauses_ = Clause::copyClauses (clauses); - } - for (size_t i = 0; i < clauses.size(); i++) { - const Literals& literals = clauses[i]->literals(); - for (size_t j = 0; j < literals.size(); j++) { - if (literals[j].isGround ( - clauses[i]->constr(), clauses[i]->ipgLogVars())) { - - Clause* c1 = lwcnf_->createClause (literals[j].lid()); - Clause* c2 = new Clause (*c1); - c2->literals().front().complement(); - - Clauses otherClauses = Clause::copyClauses (clauses); - clauses.push_back (c1); - otherClauses.push_back (c2); - - OrNode* orNode = new OrNode(); - if (Globals::verbosity > 1) { - originClausesMap_[orNode] = backupClauses_; - stringstream explanation; - explanation << " SD on " << literals[j]; - explanationMap_[orNode] = explanation.str(); - } - - compile (orNode->leftBranch(), clauses); - compile (orNode->rightBranch(), otherClauses); - (*follow) = orNode; - return true; - } - } - } - if (Globals::verbosity > 1) { - Clause::deleteClauses (backupClauses_); - } - return false; -} - - - -bool -LiftedCircuit::tryInclusionExclusion ( - CircuitNode** follow, - Clauses& clauses) -{ - if (Globals::verbosity > 1) { - backupClauses_ = Clause::copyClauses (clauses); - } - for (size_t i = 0; i < clauses.size(); i++) { - Literals depLits = { clauses[i]->literals().front() }; - Literals indepLits (clauses[i]->literals().begin() + 1, - clauses[i]->literals().end()); - bool finish = false; - while (finish == false) { - finish = true; - for (size_t j = 0; j < indepLits.size(); j++) { - if (independentLiteral (indepLits[j], depLits) == false) { - depLits.push_back (indepLits[j]); - indepLits.erase (indepLits.begin() + j); - finish = false; - break; - } - } - } - if (indepLits.empty() == false) { - LogVarSet lvs1; - for (size_t j = 0; j < depLits.size(); j++) { - lvs1 |= depLits[j].logVarSet(); - } - if (clauses[i]->constr().isCountNormalized (lvs1) == false) { - break; - } - LogVarSet lvs2; - for (size_t j = 0; j < indepLits.size(); j++) { - lvs2 |= indepLits[j].logVarSet(); - } - if (clauses[i]->constr().isCountNormalized (lvs2) == false) { - break; - } - Clause* c1 = new Clause (clauses[i]->constr().projectedCopy (lvs1)); - for (size_t j = 0; j < depLits.size(); j++) { - c1->addLiteral (depLits[j]); - } - Clause* c2 = new Clause (clauses[i]->constr().projectedCopy (lvs2)); - for (size_t j = 0; j < indepLits.size(); j++) { - c2->addLiteral (indepLits[j]); - } - - clauses.erase (clauses.begin() + i); - Clauses plus1Clauses = Clause::copyClauses (clauses); - Clauses plus2Clauses = Clause::copyClauses (clauses); - - plus1Clauses.push_back (c1); - plus2Clauses.push_back (c2); - clauses.push_back (c1); - clauses.push_back (c2); - - IncExcNode* ieNode = new IncExcNode(); - if (Globals::verbosity > 1) { - originClausesMap_[ieNode] = backupClauses_; - stringstream explanation; - explanation << " IncExc on clause nº " << i + 1; - explanationMap_[ieNode] = explanation.str(); - } - compile (ieNode->plus1Branch(), plus1Clauses); - compile (ieNode->plus2Branch(), plus2Clauses); - compile (ieNode->minusBranch(), clauses); - *follow = ieNode; - return true; - } - } - if (Globals::verbosity > 1) { - Clause::deleteClauses (backupClauses_); - } - return false; -} - - - -bool -LiftedCircuit::tryIndepPartialGrounding ( - CircuitNode** follow, - Clauses& clauses) -{ - // assumes that all literals have logical variables - // else, shannon decomp was possible - if (Globals::verbosity > 1) { - backupClauses_ = Clause::copyClauses (clauses); - } - LogVars rootLogVars; - LogVarSet lvs = clauses[0]->ipgCandidates(); - for (size_t i = 0; i < lvs.size(); i++) { - rootLogVars.clear(); - rootLogVars.push_back (lvs[i]); - ConstraintTree ct = clauses[0]->constr().projectedCopy ({lvs[i]}); - if (tryIndepPartialGroundingAux (clauses, ct, rootLogVars)) { - for (size_t j = 0; j < clauses.size(); j++) { - clauses[j]->addIpgLogVar (rootLogVars[j]); - } - SetAndNode* setAndNode = new SetAndNode (ct.size()); - if (Globals::verbosity > 1) { - originClausesMap_[setAndNode] = backupClauses_; - explanationMap_[setAndNode] = " IPG" ; - } - *follow = setAndNode; - compile (setAndNode->follow(), clauses); - return true; - } - } - if (Globals::verbosity > 1) { - Clause::deleteClauses (backupClauses_); - } - return false; -} - - - -bool -LiftedCircuit::tryIndepPartialGroundingAux ( - Clauses& clauses, - ConstraintTree& ct, - LogVars& rootLogVars) -{ - for (size_t i = 1; i < clauses.size(); i++) { - LogVarSet lvs = clauses[i]->ipgCandidates(); - for (size_t j = 0; j < lvs.size(); j++) { - ConstraintTree ct2 = clauses[i]->constr().projectedCopy ({lvs[j]}); - if (ct.tupleSet() == ct2.tupleSet()) { - rootLogVars.push_back (lvs[j]); - break; - } - } - if (rootLogVars.size() != i + 1) { - return false; - } - } - // verifies if the IPG logical vars appear in the same positions - unordered_map positions; - for (size_t i = 0; i < clauses.size(); i++) { - const Literals& literals = clauses[i]->literals(); - for (size_t j = 0; j < literals.size(); j++) { - size_t idx = literals[j].indexOfLogVar (rootLogVars[i]); - assert (idx != literals[j].nrLogVars()); - unordered_map::iterator it; - it = positions.find (literals[j].lid()); - if (it != positions.end()) { - if (it->second != idx) { - return false; - } - } else { - positions[literals[j].lid()] = idx; - } - } - } - return true; -} - - - -bool -LiftedCircuit::tryAtomCounting ( - CircuitNode** follow, - Clauses& clauses) -{ - for (size_t i = 0; i < clauses.size(); i++) { - if (clauses[i]->nrPosCountedLogVars() > 0 - || clauses[i]->nrNegCountedLogVars() > 0) { - // only allow one atom counting node per branch - return false; - } - } - if (Globals::verbosity > 1) { - backupClauses_ = Clause::copyClauses (clauses); - } - for (size_t i = 0; i < clauses.size(); i++) { - Literals literals = clauses[i]->literals(); - for (size_t j = 0; j < literals.size(); j++) { - if (literals[j].nrLogVars() == 1 - && ! clauses[i]->isIpgLogVar (literals[j].logVars().front()) - && ! clauses[i]->isCountedLogVar (literals[j].logVars().front())) { - unsigned nrGroundings = clauses[i]->constr().projectedCopy ( - literals[j].logVars()).size(); - SetOrNode* setOrNode = new SetOrNode (nrGroundings); - if (Globals::verbosity > 1) { - originClausesMap_[setOrNode] = backupClauses_; - explanationMap_[setOrNode] = " AC" ; - } - Clause* c1 = new Clause ( - clauses[i]->constr().projectedCopy (literals[j].logVars())); - Clause* c2 = new Clause ( - clauses[i]->constr().projectedCopy (literals[j].logVars())); - c1->addLiteral (literals[j]); - c2->addLiteralComplemented (literals[j]); - c1->addPosCountedLogVar (literals[j].logVars().front()); - c2->addNegCountedLogVar (literals[j].logVars().front()); - clauses.push_back (c1); - clauses.push_back (c2); - shatterCountedLogVars (clauses); - compile (setOrNode->follow(), clauses); - *follow = setOrNode; - return true; - } - } - } - if (Globals::verbosity > 1) { - Clause::deleteClauses (backupClauses_); - } - return false; -} - - - -void -LiftedCircuit::shatterCountedLogVars (Clauses& clauses) -{ - while (shatterCountedLogVarsAux (clauses)) ; -} - - - -bool -LiftedCircuit::shatterCountedLogVarsAux (Clauses& clauses) -{ - for (size_t i = 0; i < clauses.size() - 1; i++) { - for (size_t j = i + 1; j < clauses.size(); j++) { - bool splitedSome = shatterCountedLogVarsAux (clauses, i, j); - if (splitedSome) { - return true; - } - } - } - return false; -} - - - -bool -LiftedCircuit::shatterCountedLogVarsAux ( - Clauses& clauses, - size_t idx1, - size_t idx2) -{ - Literals lits1 = clauses[idx1]->literals(); - Literals lits2 = clauses[idx2]->literals(); - for (size_t i = 0; i < lits1.size(); i++) { - for (size_t j = 0; j < lits2.size(); j++) { - if (lits1[i].lid() == lits2[j].lid()) { - LogVars lvs1 = lits1[i].logVars(); - LogVars lvs2 = lits2[j].logVars(); - for (size_t k = 0; k < lvs1.size(); k++) { - if (clauses[idx1]->isCountedLogVar (lvs1[k]) - && clauses[idx2]->isCountedLogVar (lvs2[k]) == false) { - clauses.push_back (new Clause (*clauses[idx2])); - clauses[idx2]->addPosCountedLogVar (lvs2[k]); - clauses.back()->addNegCountedLogVar (lvs2[k]); - return true; - } - if (clauses[idx2]->isCountedLogVar (lvs2[k]) - && clauses[idx1]->isCountedLogVar (lvs1[k]) == false) { - clauses.push_back (new Clause (*clauses[idx1])); - clauses[idx1]->addPosCountedLogVar (lvs1[k]); - clauses.back()->addNegCountedLogVar (lvs1[k]); - return true; - } - } - } - } - } - return false; -} - - - -bool -LiftedCircuit::independentClause ( - Clause& clause, - Clauses& otherClauses) const -{ - for (size_t i = 0; i < otherClauses.size(); i++) { - if (Clause::independentClauses (clause, *otherClauses[i]) == false) { - return false; - } - } - return true; -} - - - -bool -LiftedCircuit::independentLiteral ( - const Literal& lit, - const Literals& otherLits) const -{ - for (size_t i = 0; i < otherLits.size(); i++) { - if (lit.lid() == otherLits[i].lid() - || (lit.logVarSet() & otherLits[i].logVarSet()).empty() == false) { - return false; - } - } - return true; -} - - - -LitLvTypesSet -LiftedCircuit::smoothCircuit (CircuitNode* node) -{ - assert (node != 0); - LitLvTypesSet propagLits; - - switch (getCircuitNodeType (node)) { - - case CircuitNodeType::OR_NODE: { - OrNode* casted = dynamic_cast(node); - LitLvTypesSet lids1 = smoothCircuit (*casted->leftBranch()); - LitLvTypesSet lids2 = smoothCircuit (*casted->rightBranch()); - LitLvTypesSet missingLeft = lids2 - lids1; - LitLvTypesSet missingRight = lids1 - lids2; - createSmoothNode (missingLeft, casted->leftBranch()); - createSmoothNode (missingRight, casted->rightBranch()); - propagLits |= lids1; - propagLits |= lids2; - break; - } - - case CircuitNodeType::AND_NODE: { - AndNode* casted = dynamic_cast(node); - LitLvTypesSet lids1 = smoothCircuit (*casted->leftBranch()); - LitLvTypesSet lids2 = smoothCircuit (*casted->rightBranch()); - propagLits |= lids1; - propagLits |= lids2; - break; - } - - case CircuitNodeType::SET_OR_NODE: { - SetOrNode* casted = dynamic_cast(node); - propagLits = smoothCircuit (*casted->follow()); - TinySet> litSet; - for (size_t i = 0; i < propagLits.size(); i++) { - litSet.insert (make_pair (propagLits[i].lid(), - propagLits[i].logVarTypes().size())); - } - LitLvTypesSet missingLids; - for (size_t i = 0; i < litSet.size(); i++) { - vector allTypes = getAllPossibleTypes (litSet[i].second); - for (size_t j = 0; j < allTypes.size(); j++) { - bool typeFound = false; - for (size_t k = 0; k < propagLits.size(); k++) { - if (litSet[i].first == propagLits[k].lid() - && containsTypes (propagLits[k].logVarTypes(), allTypes[j])) { - typeFound = true; - break; - } - } - if (typeFound == false) { - missingLids.insert (LitLvTypes (litSet[i].first, allTypes[j])); - } - } - } - createSmoothNode (missingLids, casted->follow()); - // setAllFullLogVars() can cause repeated elements in - // the set. Fix this by reconstructing the set again - LitLvTypesSet copy = propagLits; - propagLits.clear(); - for (size_t i = 0; i < copy.size(); i++) { - copy[i].setAllFullLogVars(); - propagLits.insert (copy[i]); - } - break; - } - - case CircuitNodeType::SET_AND_NODE: { - SetAndNode* casted = dynamic_cast(node); - propagLits = smoothCircuit (*casted->follow()); - break; - } - - case CircuitNodeType::INC_EXC_NODE: { - IncExcNode* casted = dynamic_cast(node); - LitLvTypesSet lids1 = smoothCircuit (*casted->plus1Branch()); - LitLvTypesSet lids2 = smoothCircuit (*casted->plus2Branch()); - LitLvTypesSet missingPlus1 = lids2 - lids1; - LitLvTypesSet missingPlus2 = lids1 - lids2; - createSmoothNode (missingPlus1, casted->plus1Branch()); - createSmoothNode (missingPlus2, casted->plus2Branch()); - propagLits |= lids1; - propagLits |= lids2; - break; - } - - case CircuitNodeType::LEAF_NODE: { - LeafNode* casted = dynamic_cast(node); - propagLits.insert (LitLvTypes ( - casted->clause()->literals()[0].lid(), - casted->clause()->logVarTypes(0))); - } - - default: - break; - } - - return propagLits; -} - - - -void -LiftedCircuit::createSmoothNode ( - const LitLvTypesSet& missingLits, - CircuitNode** prev) -{ - if (missingLits.empty() == false) { - if (Globals::verbosity > 1) { - unordered_map::iterator it; - it = originClausesMap_.find (*prev); - if (it != originClausesMap_.end()) { - backupClauses_ = it->second; - } else { - backupClauses_ = Clause::copyClauses ( - {((dynamic_cast(*prev))->clause())}); - } - } - Clauses clauses; - for (size_t i = 0; i < missingLits.size(); i++) { - LiteralId lid = missingLits[i].lid(); - const LogVarTypes& types = missingLits[i].logVarTypes(); - Clause* c = lwcnf_->createClause (lid); - for (size_t j = 0; j < types.size(); j++) { - LogVar X = c->literals().front().logVars()[j]; - if (types[j] == LogVarType::POS_LV) { - c->addPosCountedLogVar (X); - } else if (types[j] == LogVarType::NEG_LV) { - c->addNegCountedLogVar (X); - } - } - c->addLiteralComplemented (c->literals()[0]); - clauses.push_back (c); - } - SmoothNode* smoothNode = new SmoothNode (clauses, *lwcnf_); - *prev = new AndNode (smoothNode, *prev); - if (Globals::verbosity > 1) { - originClausesMap_[*prev] = backupClauses_; - explanationMap_[*prev] = " Smoothing" ; - } - } -} - - - -vector -LiftedCircuit::getAllPossibleTypes (unsigned nrLogVars) const -{ - if (nrLogVars == 0) { - return {}; - } - if (nrLogVars == 1) { - return {{LogVarType::POS_LV},{LogVarType::NEG_LV}}; - } - vector res; - Ranges ranges (nrLogVars, 2); - Indexer indexer (ranges); - while (indexer.valid()) { - LogVarTypes types; - for (size_t i = 0; i < nrLogVars; i++) { - if (indexer[i] == 0) { - types.push_back (LogVarType::POS_LV); - } else { - types.push_back (LogVarType::NEG_LV); - } - } - res.push_back (types); - ++ indexer; - } - return res; -} - - - -bool -LiftedCircuit::containsTypes ( - const LogVarTypes& typesA, - const LogVarTypes& typesB) const -{ - for (size_t i = 0; i < typesA.size(); i++) { - if (typesA[i] == LogVarType::FULL_LV) { - - } else if (typesA[i] == LogVarType::POS_LV - && typesB[i] == LogVarType::POS_LV) { - - } else if (typesA[i] == LogVarType::NEG_LV - && typesB[i] == LogVarType::NEG_LV) { - - } else { - return false; - } - } - return true; -} - - - -CircuitNodeType -LiftedCircuit::getCircuitNodeType (const CircuitNode* node) const -{ - CircuitNodeType type; - if (dynamic_cast(node) != 0) { - type = CircuitNodeType::OR_NODE; - } else if (dynamic_cast(node) != 0) { - type = CircuitNodeType::AND_NODE; - } else if (dynamic_cast(node) != 0) { - type = CircuitNodeType::SET_OR_NODE; - } else if (dynamic_cast(node) != 0) { - type = CircuitNodeType::SET_AND_NODE; - } else if (dynamic_cast(node) != 0) { - type = CircuitNodeType::INC_EXC_NODE; - } else if (dynamic_cast(node) != 0) { - type = CircuitNodeType::LEAF_NODE; - } else if (dynamic_cast(node) != 0) { - type = CircuitNodeType::SMOOTH_NODE; - } else if (dynamic_cast(node) != 0) { - type = CircuitNodeType::TRUE_NODE; - } else if (dynamic_cast(node) != 0) { - type = CircuitNodeType::COMPILATION_FAILED_NODE; - } else { - assert (false); - } - return type; -} - - - -void -LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) -{ - assert (node != 0); - - static unsigned nrAuxNodes = 0; - stringstream ss; - ss << "n" << nrAuxNodes; - string auxNode = ss.str(); - nrAuxNodes ++; - string opStyle = "shape=circle,width=0.7,margin=\"0.0,0.0\"," ; - - switch (getCircuitNodeType (node)) { - - case OR_NODE: { - OrNode* casted = dynamic_cast(node); - printClauses (casted, os); - - os << auxNode << " [" << opStyle << "label=\"∨\"]" << endl; - os << escapeNode (node) << " -> " << auxNode; - os << " [label=\"" << getExplanationString (node) << "\"]" ; - os << endl; - - os << auxNode << " -> " ; - os << escapeNode (*casted->leftBranch()); - os << " [label=\" " << (*casted->leftBranch())->weight() << "\"]" ; - os << endl; - - os << auxNode << " -> " ; - os << escapeNode (*casted->rightBranch()); - os << " [label=\" " << (*casted->rightBranch())->weight() << "\"]" ; - os << endl; - - exportToGraphViz (*casted->leftBranch(), os); - exportToGraphViz (*casted->rightBranch(), os); - break; - } - - case AND_NODE: { - AndNode* casted = dynamic_cast(node); - printClauses (casted, os); - - os << auxNode << " [" << opStyle << "label=\"∧\"]" << endl; - os << escapeNode (node) << " -> " << auxNode; - os << " [label=\"" << getExplanationString (node) << "\"]" ; - os << endl; - - os << auxNode << " -> " ; - os << escapeNode (*casted->leftBranch()); - os << " [label=\" " << (*casted->leftBranch())->weight() << "\"]" ; - os << endl; - - os << auxNode << " -> " ; - os << escapeNode (*casted->rightBranch()) << endl; - os << " [label=\" " << (*casted->rightBranch())->weight() << "\"]" ; - os << endl; - - exportToGraphViz (*casted->leftBranch(), os); - exportToGraphViz (*casted->rightBranch(), os); - break; - } - - case SET_OR_NODE: { - SetOrNode* casted = dynamic_cast(node); - printClauses (casted, os); - - os << auxNode << " [" << opStyle << "label=\"∨(X)\"]" << endl; - os << escapeNode (node) << " -> " << auxNode; - os << " [label=\"" << getExplanationString (node) << "\"]" ; - os << endl; - - os << auxNode << " -> " ; - os << escapeNode (*casted->follow()); - os << " [label=\" " << (*casted->follow())->weight() << "\"]" ; - os << endl; - - exportToGraphViz (*casted->follow(), os); - break; - } - - case SET_AND_NODE: { - SetAndNode* casted = dynamic_cast(node); - printClauses (casted, os); - - os << auxNode << " [" << opStyle << "label=\"∧(X)\"]" << endl; - os << escapeNode (node) << " -> " << auxNode; - os << " [label=\"" << getExplanationString (node) << "\"]" ; - os << endl; - - os << auxNode << " -> " ; - os << escapeNode (*casted->follow()); - os << " [label=\" " << (*casted->follow())->weight() << "\"]" ; - os << endl; - - exportToGraphViz (*casted->follow(), os); - break; - } - - case INC_EXC_NODE: { - IncExcNode* casted = dynamic_cast(node); - printClauses (casted, os); - - os << auxNode << " [" << opStyle << "label=\"+ - +\"]" ; - os << endl; - os << escapeNode (node) << " -> " << auxNode; - os << " [label=\"" << getExplanationString (node) << "\"]" ; - os << endl; - - os << auxNode << " -> " ; - os << escapeNode (*casted->plus1Branch()); - os << " [label=\" " << (*casted->plus1Branch())->weight() << "\"]" ; - os << endl; - - os << auxNode << " -> " ; - os << escapeNode (*casted->minusBranch()) << endl; - os << " [label=\" " << (*casted->minusBranch())->weight() << "\"]" ; - os << endl; - - os << auxNode << " -> " ; - os << escapeNode (*casted->plus2Branch()); - os << " [label=\" " << (*casted->plus2Branch())->weight() << "\"]" ; - os << endl; - - exportToGraphViz (*casted->plus1Branch(), os); - exportToGraphViz (*casted->plus2Branch(), os); - exportToGraphViz (*casted->minusBranch(), os); - break; - } - - case LEAF_NODE: { - printClauses (node, os, "style=filled,fillcolor=palegreen,"); - break; - } - - case SMOOTH_NODE: { - printClauses (node, os, "style=filled,fillcolor=lightblue,"); - break; - } - - case TRUE_NODE: { - os << escapeNode (node); - os << " [shape=box,label=\"⊤\"]" ; - os << endl; - break; - } - - case COMPILATION_FAILED_NODE: { - printClauses (node, os, "style=filled,fillcolor=salmon,"); - break; - } - - default: - assert (false); - } -} - - - -string -LiftedCircuit::escapeNode (const CircuitNode* node) const -{ - stringstream ss; - ss << "\"" << node << "\"" ; - return ss.str(); -} - - - -string -LiftedCircuit::getExplanationString (CircuitNode* node) -{ - return Util::contains (explanationMap_, node) - ? explanationMap_[node] - : "" ; -} - - - -void -LiftedCircuit::printClauses ( - CircuitNode* node, - ofstream& os, - string extraOptions) -{ - Clauses clauses; - if (Util::contains (originClausesMap_, node)) { - clauses = originClausesMap_[node]; - } else if (getCircuitNodeType (node) == CircuitNodeType::LEAF_NODE) { - clauses = { (dynamic_cast(node))->clause() } ; - } else if (getCircuitNodeType (node) == CircuitNodeType::SMOOTH_NODE) { - clauses = (dynamic_cast(node))->clauses(); - } - assert (clauses.empty() == false); - os << escapeNode (node); - os << " [shape=box," << extraOptions << "label=\"" ; - for (size_t i = 0; i < clauses.size(); i++) { - if (i != 0) os << "\\n" ; - os << *clauses[i]; - } - os << "\"]" ; - os << endl; -} - - - -LiftedKc::~LiftedKc (void) -{ - delete lwcnf_; - delete circuit_; -} - - - -Params -LiftedKc::solveQuery (const Grounds& query) -{ - pfList_ = parfactorList; - LiftedOperations::shatterAgainstQuery (pfList_, query); - LiftedOperations::runWeakBayesBall (pfList_, query); - lwcnf_ = new LiftedWCNF (pfList_); - circuit_ = new LiftedCircuit (lwcnf_); - if (circuit_->isCompilationSucceeded() == false) { - cerr << "Error: the circuit compilation has failed." << endl; - exit (EXIT_FAILURE); - } - vector groups; - Ranges ranges; - for (size_t i = 0; i < query.size(); i++) { - ParfactorList::const_iterator it = pfList_.begin(); - while (it != pfList_.end()) { - size_t idx = (*it)->indexOfGround (query[i]); - if (idx != (*it)->nrArguments()) { - groups.push_back ((*it)->argument (idx).group()); - ranges.push_back ((*it)->range (idx)); - break; - } - ++ it; - } - } - assert (groups.size() == query.size()); - Params params; - Indexer indexer (ranges); - while (indexer.valid()) { - for (size_t i = 0; i < groups.size(); i++) { - vector litIds = lwcnf_->prvGroupLiterals (groups[i]); - for (size_t j = 0; j < litIds.size(); j++) { - if (indexer[i] == j) { - lwcnf_->addWeight (litIds[j], LogAware::one(), - LogAware::one()); - } else { - lwcnf_->addWeight (litIds[j], LogAware::zero(), - LogAware::one()); - } - } - } - params.push_back (circuit_->getWeightedModelCount()); - ++ indexer; - } - LogAware::normalize (params); - if (Globals::logDomain) { - Util::exp (params); - } - return params; -} - - - -void -LiftedKc::printSolverFlags (void) const -{ - stringstream ss; - ss << "lifted kc [" ; - ss << "log_domain=" << Util::toString (Globals::logDomain); - ss << "]" ; - cout << ss.str() << endl; -} - diff --git a/packages/CLPBN/horus2/LiftedKc.h b/packages/CLPBN/horus2/LiftedKc.h deleted file mode 100644 index a4cd2dbeb..000000000 --- a/packages/CLPBN/horus2/LiftedKc.h +++ /dev/null @@ -1,300 +0,0 @@ -#ifndef HORUS_LIFTEDKC_H -#define HORUS_LIFTEDKC_H - - -#include "LiftedWCNF.h" -#include "LiftedSolver.h" -#include "ParfactorList.h" - - -enum CircuitNodeType { - OR_NODE, - AND_NODE, - SET_OR_NODE, - SET_AND_NODE, - INC_EXC_NODE, - LEAF_NODE, - SMOOTH_NODE, - TRUE_NODE, - COMPILATION_FAILED_NODE -}; - - - -class CircuitNode -{ - public: - CircuitNode (void) { } - - virtual ~CircuitNode (void) { } - - virtual double weight (void) const = 0; -}; - - - -class OrNode : public CircuitNode -{ - public: - OrNode (void) : CircuitNode(), leftBranch_(0), rightBranch_(0) { } - - ~OrNode (void); - - CircuitNode** leftBranch (void) { return &leftBranch_; } - CircuitNode** rightBranch (void) { return &rightBranch_; } - - double weight (void) const; - - private: - CircuitNode* leftBranch_; - CircuitNode* rightBranch_; -}; - - - -class AndNode : public CircuitNode -{ - public: - AndNode (void) : CircuitNode(), leftBranch_(0), rightBranch_(0) { } - - AndNode (CircuitNode* leftBranch, CircuitNode* rightBranch) - : CircuitNode(), leftBranch_(leftBranch), rightBranch_(rightBranch) { } - - ~AndNode (void); - - CircuitNode** leftBranch (void) { return &leftBranch_; } - CircuitNode** rightBranch (void) { return &rightBranch_; } - - double weight (void) const; - - private: - CircuitNode* leftBranch_; - CircuitNode* rightBranch_; -}; - - - -class SetOrNode : public CircuitNode -{ - public: - SetOrNode (unsigned nrGroundings) - : CircuitNode(), follow_(0), nrGroundings_(nrGroundings) { } - - ~SetOrNode (void); - - CircuitNode** follow (void) { return &follow_; } - - static unsigned nrPositives (void) { return nrPos_; } - - static unsigned nrNegatives (void) { return nrNeg_; } - - static bool isSet (void) { return nrPos_ >= 0; } - - double weight (void) const; - - private: - CircuitNode* follow_; - unsigned nrGroundings_; - static int nrPos_; - static int nrNeg_; -}; - - - -class SetAndNode : public CircuitNode -{ - public: - SetAndNode (unsigned nrGroundings) - : CircuitNode(), follow_(0), nrGroundings_(nrGroundings) { } - - ~SetAndNode (void); - - CircuitNode** follow (void) { return &follow_; } - - double weight (void) const; - - private: - CircuitNode* follow_; - unsigned nrGroundings_; -}; - - - -class IncExcNode : public CircuitNode -{ - public: - IncExcNode (void) - : CircuitNode(), plus1Branch_(0), plus2Branch_(0), minusBranch_(0) { } - - ~IncExcNode (void); - - CircuitNode** plus1Branch (void) { return &plus1Branch_; } - CircuitNode** plus2Branch (void) { return &plus2Branch_; } - CircuitNode** minusBranch (void) { return &minusBranch_; } - - double weight (void) const; - - private: - CircuitNode* plus1Branch_; - CircuitNode* plus2Branch_; - CircuitNode* minusBranch_; -}; - - - -class LeafNode : public CircuitNode -{ - public: - LeafNode (Clause* clause, const LiftedWCNF& lwcnf) - : CircuitNode(), clause_(clause), lwcnf_(lwcnf) { } - - ~LeafNode (void); - - const Clause* clause (void) const { return clause_; } - - Clause* clause (void) { return clause_; } - - double weight (void) const; - - private: - Clause* clause_; - const LiftedWCNF& lwcnf_; -}; - - - -class SmoothNode : public CircuitNode -{ - public: - SmoothNode (const Clauses& clauses, const LiftedWCNF& lwcnf) - : CircuitNode(), clauses_(clauses), lwcnf_(lwcnf) { } - - ~SmoothNode (void); - - const Clauses& clauses (void) const { return clauses_; } - - Clauses clauses (void) { return clauses_; } - - double weight (void) const; - - private: - Clauses clauses_; - const LiftedWCNF& lwcnf_; -}; - - - -class TrueNode : public CircuitNode -{ - public: - TrueNode (void) : CircuitNode() { } - - double weight (void) const; -}; - - - -class CompilationFailedNode : public CircuitNode -{ - public: - CompilationFailedNode (void) : CircuitNode() { } - - double weight (void) const; -}; - - - -class LiftedCircuit -{ - public: - LiftedCircuit (const LiftedWCNF* lwcnf); - - ~LiftedCircuit (void); - - bool isCompilationSucceeded (void) const; - - double getWeightedModelCount (void) const; - - void exportToGraphViz (const char*); - - private: - - void compile (CircuitNode** follow, Clauses& clauses); - - bool tryUnitPropagation (CircuitNode** follow, Clauses& clauses); - - bool tryIndependence (CircuitNode** follow, Clauses& clauses); - - bool tryShannonDecomp (CircuitNode** follow, Clauses& clauses); - - bool tryInclusionExclusion (CircuitNode** follow, Clauses& clauses); - - bool tryIndepPartialGrounding (CircuitNode** follow, Clauses& clauses); - - bool tryIndepPartialGroundingAux (Clauses& clauses, ConstraintTree& ct, - LogVars& rootLogVars); - - bool tryAtomCounting (CircuitNode** follow, Clauses& clauses); - - void shatterCountedLogVars (Clauses& clauses); - - bool shatterCountedLogVarsAux (Clauses& clauses); - - bool shatterCountedLogVarsAux (Clauses& clauses, size_t idx1, size_t idx2); - - bool independentClause (Clause& clause, Clauses& otherClauses) const; - - bool independentLiteral (const Literal& lit, - const Literals& otherLits) const; - - LitLvTypesSet smoothCircuit (CircuitNode* node); - - void createSmoothNode (const LitLvTypesSet& lids, - CircuitNode** prev); - - vector getAllPossibleTypes (unsigned nrLogVars) const; - - bool containsTypes (const LogVarTypes& typesA, - const LogVarTypes& typesB) const; - - CircuitNodeType getCircuitNodeType (const CircuitNode* node) const; - - void exportToGraphViz (CircuitNode* node, ofstream&); - - void printClauses (CircuitNode* node, ofstream&, - string extraOptions = ""); - - string escapeNode (const CircuitNode* node) const; - - string getExplanationString (CircuitNode* node); - - CircuitNode* root_; - const LiftedWCNF* lwcnf_; - bool compilationSucceeded_; - Clauses backupClauses_; - unordered_map originClausesMap_; - unordered_map explanationMap_; -}; - - - -class LiftedKc : public LiftedSolver -{ - public: - LiftedKc (const ParfactorList& pfList) - : LiftedSolver(pfList) { } - - ~LiftedKc (void); - - Params solveQuery (const Grounds&); - - void printSolverFlags (void) const; - - private: - LiftedWCNF* lwcnf_; - LiftedCircuit* circuit_; - ParfactorList pfList_; -}; - -#endif // HORUS_LIFTEDKC_H - diff --git a/packages/CLPBN/horus2/LiftedOperations.cpp b/packages/CLPBN/horus2/LiftedOperations.cpp deleted file mode 100644 index e0da2dd3b..000000000 --- a/packages/CLPBN/horus2/LiftedOperations.cpp +++ /dev/null @@ -1,271 +0,0 @@ -#include "LiftedOperations.h" - - -void -LiftedOperations::shatterAgainstQuery ( - ParfactorList& pfList, - const Grounds& query) -{ - for (size_t i = 0; i < query.size(); i++) { - if (query[i].isAtom()) { - continue; - } - bool found = false; - Parfactors newPfs; - ParfactorList::iterator it = pfList.begin(); - while (it != pfList.end()) { - if ((*it)->containsGround (query[i])) { - found = true; - std::pair split; - LogVars queryLvs ( - (*it)->constr()->logVars().begin(), - (*it)->constr()->logVars().begin() + query[i].arity()); - split = (*it)->constr()->split (query[i].args()); - ConstraintTree* commCt = split.first; - ConstraintTree* exclCt = split.second; - newPfs.push_back (new Parfactor (*it, commCt)); - if (exclCt->empty() == false) { - newPfs.push_back (new Parfactor (*it, exclCt)); - } else { - delete exclCt; - } - it = pfList.removeAndDelete (it); - } else { - ++ it; - } - } - if (found == false) { - cerr << "Error: could not find a parfactor with ground " ; - cerr << "`" << query[i] << "'." << endl; - exit (EXIT_FAILURE); - } - pfList.add (newPfs); - } - if (Globals::verbosity > 2) { - Util::printAsteriskLine(); - cout << "SHATTERED AGAINST THE QUERY" << endl; - for (size_t i = 0; i < query.size(); i++) { - cout << " -> " << query[i] << endl; - } - Util::printAsteriskLine(); - pfList.print(); - } -} - - - -void -LiftedOperations::runWeakBayesBall ( - ParfactorList& pfList, - const Grounds& query) -{ - queue todo; // groups to process - set done; // processed or in queue - for (size_t i = 0; i < query.size(); i++) { - ParfactorList::iterator it = pfList.begin(); - while (it != pfList.end()) { - PrvGroup group = (*it)->findGroup (query[i]); - if (group != numeric_limits::max()) { - todo.push (group); - done.insert (group); - break; - } - ++ it; - } - } - - set requiredPfs; - while (todo.empty() == false) { - PrvGroup group = todo.front(); - ParfactorList::iterator it = pfList.begin(); - while (it != pfList.end()) { - if (Util::contains (requiredPfs, *it) == false && - (*it)->containsGroup (group)) { - vector groups = (*it)->getAllGroups(); - for (size_t i = 0; i < groups.size(); i++) { - if (Util::contains (done, groups[i]) == false) { - todo.push (groups[i]); - done.insert (groups[i]); - } - } - requiredPfs.insert (*it); - } - ++ it; - } - todo.pop(); - } - - ParfactorList::iterator it = pfList.begin(); - bool foundNotRequired = false; - while (it != pfList.end()) { - if (Util::contains (requiredPfs, *it) == false) { - if (Globals::verbosity > 2) { - if (foundNotRequired == false) { - Util::printHeader ("PARFACTORS TO DISCARD"); - foundNotRequired = true; - } - (*it)->print(); - } - it = pfList.removeAndDelete (it); - } else { - ++ it; - } - } -} - - - -void -LiftedOperations::absorveEvidence ( - ParfactorList& pfList, - ObservedFormulas& obsFormulas) -{ - for (size_t i = 0; i < obsFormulas.size(); i++) { - Parfactors newPfs; - ParfactorList::iterator it = pfList.begin(); - while (it != pfList.end()) { - Parfactor* pf = *it; - it = pfList.remove (it); - Parfactors absorvedPfs = absorve (obsFormulas[i], pf); - if (absorvedPfs.empty() == false) { - if (absorvedPfs.size() == 1 && absorvedPfs[0] == 0) { - // just remove pf; - } else { - Util::addToVector (newPfs, absorvedPfs); - } - delete pf; - } else { - it = pfList.insertShattered (it, pf); - ++ it; - } - } - pfList.add (newPfs); - } - if (Globals::verbosity > 2 && obsFormulas.empty() == false) { - Util::printAsteriskLine(); - cout << "AFTER EVIDENCE ABSORVED" << endl; - for (size_t i = 0; i < obsFormulas.size(); i++) { - cout << " -> " << obsFormulas[i] << endl; - } - Util::printAsteriskLine(); - pfList.print(); - } -} - - - -Parfactors -LiftedOperations::countNormalize ( - Parfactor* g, - const LogVarSet& set) -{ - Parfactors normPfs; - if (set.empty()) { - normPfs.push_back (new Parfactor (*g)); - } else { - ConstraintTrees normCts = g->constr()->countNormalize (set); - for (size_t i = 0; i < normCts.size(); i++) { - normPfs.push_back (new Parfactor (g, normCts[i])); - } - } - return normPfs; -} - - - -Parfactor -LiftedOperations::calcGroundMultiplication (Parfactor pf) -{ - LogVarSet lvs = pf.constr()->logVarSet(); - lvs -= pf.constr()->singletons(); - Parfactors newPfs = {new Parfactor (pf)}; - for (size_t i = 0; i < lvs.size(); i++) { - Parfactors pfs = newPfs; - newPfs.clear(); - for (size_t j = 0; j < pfs.size(); j++) { - bool countedLv = pfs[j]->countedLogVars().contains (lvs[i]); - if (countedLv) { - pfs[j]->fullExpand (lvs[i]); - newPfs.push_back (pfs[j]); - } else { - ConstraintTrees cts = pfs[j]->constr()->ground (lvs[i]); - for (size_t k = 0; k < cts.size(); k++) { - newPfs.push_back (new Parfactor (pfs[j], cts[k])); - } - delete pfs[j]; - } - } - } - ParfactorList pfList (newPfs); - Parfactors groundShatteredPfs (pfList.begin(),pfList.end()); - for (size_t i = 1; i < groundShatteredPfs.size(); i++) { - groundShatteredPfs[0]->multiply (*groundShatteredPfs[i]); - } - return Parfactor (*groundShatteredPfs[0]); -} - - - -Parfactors -LiftedOperations::absorve ( - ObservedFormula& obsFormula, - Parfactor* g) -{ - Parfactors absorvedPfs; - const ProbFormulas& formulas = g->arguments(); - for (size_t i = 0; i < formulas.size(); i++) { - if (obsFormula.functor() == formulas[i].functor() && - obsFormula.arity() == formulas[i].arity()) { - - if (obsFormula.isAtom()) { - if (formulas.size() > 1) { - g->absorveEvidence (formulas[i], obsFormula.evidence()); - } else { - // hack to erase parfactor g - absorvedPfs.push_back (0); - } - break; - } - - g->constr()->moveToTop (formulas[i].logVars()); - std::pair res; - res = g->constr()->split ( - formulas[i].logVars(), - &(obsFormula.constr()), - obsFormula.constr().logVars()); - ConstraintTree* commCt = res.first; - ConstraintTree* exclCt = res.second; - - if (commCt->empty() == false) { - if (formulas.size() > 1) { - LogVarSet excl = g->exclusiveLogVars (i); - Parfactor tempPf (g, commCt); - Parfactors countNormPfs = LiftedOperations::countNormalize ( - &tempPf, excl); - for (size_t j = 0; j < countNormPfs.size(); j++) { - countNormPfs[j]->absorveEvidence ( - formulas[i], obsFormula.evidence()); - absorvedPfs.push_back (countNormPfs[j]); - } - } else { - delete commCt; - } - if (exclCt->empty() == false) { - absorvedPfs.push_back (new Parfactor (g, exclCt)); - } else { - delete exclCt; - } - if (absorvedPfs.empty()) { - // hack to erase parfactor g - absorvedPfs.push_back (0); - } - break; - } else { - delete commCt; - delete exclCt; - } - } - } - return absorvedPfs; -} - diff --git a/packages/CLPBN/horus2/LiftedOperations.h b/packages/CLPBN/horus2/LiftedOperations.h deleted file mode 100644 index fc25363d3..000000000 --- a/packages/CLPBN/horus2/LiftedOperations.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef HORUS_LIFTEDOPERATIONS_H -#define HORUS_LIFTEDOPERATIONS_H - -#include "ParfactorList.h" - -class LiftedOperations -{ - public: - static void shatterAgainstQuery ( - ParfactorList& pfList, const Grounds& query); - - static void runWeakBayesBall ( - ParfactorList& pfList, const Grounds&); - - static void absorveEvidence ( - ParfactorList& pfList, ObservedFormulas& obsFormulas); - - static Parfactors countNormalize (Parfactor*, const LogVarSet&); - - static Parfactor calcGroundMultiplication (Parfactor pf); - - private: - static Parfactors absorve (ObservedFormula&, Parfactor*); -}; - -#endif // HORUS_LIFTEDOPERATIONS_H - diff --git a/packages/CLPBN/horus2/LiftedSolver.h b/packages/CLPBN/horus2/LiftedSolver.h deleted file mode 100644 index 5429fc5b3..000000000 --- a/packages/CLPBN/horus2/LiftedSolver.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef HORUS_LIFTEDSOLVER_H -#define HORUS_LIFTEDSOLVER_H - -#include "ParfactorList.h" -#include "Horus.h" - - -using namespace std; - -class LiftedSolver -{ - public: - LiftedSolver (const ParfactorList& pfList) - : parfactorList(pfList) { } - - virtual ~LiftedSolver() { } // ensure that subclass destructor is called - - virtual Params solveQuery (const Grounds& query) = 0; - - virtual void printSolverFlags (void) const = 0; - - protected: - const ParfactorList& parfactorList; -}; - -#endif // HORUS_LIFTEDSOLVER_H - diff --git a/packages/CLPBN/horus2/LiftedUtils.cpp b/packages/CLPBN/horus2/LiftedUtils.cpp deleted file mode 100644 index 9ad750f90..000000000 --- a/packages/CLPBN/horus2/LiftedUtils.cpp +++ /dev/null @@ -1,131 +0,0 @@ -#include - -#include -#include -#include - -#include "LiftedUtils.h" -#include "ConstraintTree.h" - - -namespace LiftedUtils { - - -unordered_map symbolDict; - - -Symbol -getSymbol (const string& symbolName) -{ - unordered_map::iterator it - = symbolDict.find (symbolName); - if (it != symbolDict.end()) { - return it->second; - } else { - symbolDict[symbolName] = symbolDict.size() - 1; - return symbolDict.size() - 1; - } -} - - - -void -printSymbolDictionary (void) -{ - unordered_map::const_iterator it - = symbolDict.begin(); - while (it != symbolDict.end()) { - cout << it->first << " -> " << it->second << endl; - ++ it; - } -} - -} - - - -ostream& operator<< (ostream &os, const Symbol& s) -{ - unordered_map::const_iterator it - = LiftedUtils::symbolDict.begin(); - while (it != LiftedUtils::symbolDict.end() && it->second != s) { - ++ it; - } - assert (it != LiftedUtils::symbolDict.end()); - os << it->first; - return os; -} - - - -ostream& operator<< (ostream &os, const LogVar& X) -{ - const string labels[] = { - "A", "B", "C", "D", "E", "F", - "G", "H", "I", "J", "K", "M" }; - (X >= 12) ? os << "X_" << X.id_ : os << labels[X]; - return os; -} - - - -ostream& operator<< (ostream &os, const Tuple& t) -{ - os << "(" ; - for (size_t i = 0; i < t.size(); i++) { - os << ((i != 0) ? "," : "") << t[i]; - } - os << ")" ; - return os; -} - - - -ostream& operator<< (ostream &os, const Ground& gr) -{ - os << gr.functor(); - os << "(" ; - for (size_t i = 0; i < gr.args().size(); i++) { - if (i != 0) os << ", " ; - os << gr.args()[i]; - } - os << ")" ; - return os; -} - - - -LogVars -Substitution::getDiscardedLogVars (void) const -{ - LogVars discardedLvs; - set doneLvs; - unordered_map::const_iterator it; - it = subs_.begin(); - while (it != subs_.end()) { - if (Util::contains (doneLvs, it->second)) { - discardedLvs.push_back (it->first); - } else { - doneLvs.insert (it->second); - } - ++ it; - } - return discardedLvs; -} - - - -ostream& operator<< (ostream &os, const Substitution& theta) -{ - unordered_map::const_iterator it; - os << "[" ; - it = theta.subs_.begin(); - while (it != theta.subs_.end()) { - if (it != theta.subs_.begin()) os << ", " ; - os << it->first << "->" << it->second ; - ++ it; - } - os << "]" ; - return os; -} - diff --git a/packages/CLPBN/horus2/LiftedUtils.h b/packages/CLPBN/horus2/LiftedUtils.h deleted file mode 100644 index 1f563eaf7..000000000 --- a/packages/CLPBN/horus2/LiftedUtils.h +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef HORUS_LIFTEDUTILS_H -#define HORUS_LIFTEDUTILS_H - -#include -#include -#include -#include - - -#include "TinySet.h" -#include "Util.h" - - -using namespace std; - - -class Symbol -{ - public: - Symbol (void) : id_(Util::maxUnsigned()) { } - - Symbol (unsigned id) : id_(id) { } - - operator unsigned (void) const { return id_; } - - bool valid (void) const { return id_ != Util::maxUnsigned(); } - - static Symbol invalid (void) { return Symbol(); } - - friend ostream& operator<< (ostream &os, const Symbol& s); - - private: - unsigned id_; -}; - - -class LogVar -{ - public: - LogVar (void) : id_(Util::maxUnsigned()) { } - - LogVar (unsigned id) : id_(id) { } - - operator unsigned (void) const { return id_; } - - LogVar& operator++ (void) - { - assert (valid()); - id_ ++; - return *this; - } - - bool valid (void) const - { - return id_ != Util::maxUnsigned(); - } - - friend ostream& operator<< (ostream &os, const LogVar& X); - - private: - unsigned id_; -}; - - -namespace std { -template <> struct hash { - size_t operator() (const Symbol& s) const { - return std::hash() (s); - }}; - -template <> struct hash { - size_t operator() (const LogVar& X) const { - return std::hash() (X); - }}; -}; - - -typedef vector Symbols; -typedef vector Tuple; -typedef vector Tuples; -typedef vector LogVars; -typedef TinySet SymbolSet; -typedef TinySet LogVarSet; -typedef TinySet TupleSet; - - -ostream& operator<< (ostream &os, const Tuple& t); - - -namespace LiftedUtils { -Symbol getSymbol (const string&); -void printSymbolDictionary (void); -} - - - -class Ground -{ - public: - Ground (Symbol f) : functor_(f) { } - - Ground (Symbol f, const Symbols& args) : functor_(f), args_(args) { } - - Symbol functor (void) const { return functor_; } - - Symbols args (void) const { return args_; } - - size_t arity (void) const { return args_.size(); } - - bool isAtom (void) const { return args_.size() == 0; } - - friend ostream& operator<< (ostream &os, const Ground& gr); - - private: - Symbol functor_; - Symbols args_; -}; - -typedef vector Grounds; - - - -class Substitution -{ - public: - void add (LogVar X_old, LogVar X_new) - { - assert (Util::contains (subs_, X_old) == false); - subs_.insert (make_pair (X_old, X_new)); - } - - void rename (LogVar X_old, LogVar X_new) - { - assert (Util::contains (subs_, X_old)); - subs_.find (X_old)->second = X_new; - } - - LogVar newNameFor (LogVar X) const - { - unordered_map::const_iterator it; - it = subs_.find (X); - if (it != subs_.end()) { - return subs_.find (X)->second; - } - return X; - } - - bool containsReplacementFor (LogVar X) const - { - return Util::contains (subs_, X); - } - - size_t nrReplacements (void) const { return subs_.size(); } - - LogVars getDiscardedLogVars (void) const; - - friend ostream& operator<< (ostream &os, const Substitution& theta); - - private: - unordered_map subs_; - -}; - - -#endif // HORUS_LIFTEDUTILS_H - diff --git a/packages/CLPBN/horus2/LiftedVe.cpp b/packages/CLPBN/horus2/LiftedVe.cpp deleted file mode 100644 index 141006c46..000000000 --- a/packages/CLPBN/horus2/LiftedVe.cpp +++ /dev/null @@ -1,728 +0,0 @@ -#include -#include - -#include "LiftedVe.h" -#include "LiftedOperations.h" -#include "Histogram.h" -#include "Util.h" - - -vector -LiftedOperator::getValidOps ( - ParfactorList& pfList, - const Grounds& query) -{ - vector validOps; - vector multOps; - - multOps = ProductOperator::getValidOps (pfList); - validOps.insert (validOps.end(), multOps.begin(), multOps.end()); - - if (Globals::verbosity > 1 || multOps.empty()) { - vector sumOutOps; - vector countOps; - vector groundOps; - sumOutOps = SumOutOperator::getValidOps (pfList, query); - countOps = CountingOperator::getValidOps (pfList); - groundOps = GroundOperator::getValidOps (pfList); - validOps.insert (validOps.end(), sumOutOps.begin(), sumOutOps.end()); - validOps.insert (validOps.end(), countOps.begin(), countOps.end()); - validOps.insert (validOps.end(), groundOps.begin(), groundOps.end()); - } - - return validOps; -} - - - -void -LiftedOperator::printValidOps ( - ParfactorList& pfList, - const Grounds& query) -{ - vector validOps; - validOps = LiftedOperator::getValidOps (pfList, query); - for (size_t i = 0; i < validOps.size(); i++) { - cout << "-> " << validOps[i]->toString(); - delete validOps[i]; - } -} - - - -vector -LiftedOperator::getParfactorsWithGroup ( - ParfactorList& pfList, PrvGroup group) -{ - vector iters; - ParfactorList::iterator pflIt = pfList.begin(); - while (pflIt != pfList.end()) { - if ((*pflIt)->containsGroup (group)) { - iters.push_back (pflIt); - } - ++ pflIt; - } - return iters; -} - - - -double -ProductOperator::getLogCost (void) -{ - return std::log (0.0); -} - - - -void -ProductOperator::apply (void) -{ - Parfactor* g1 = *g1_; - Parfactor* g2 = *g2_; - g1->multiply (*g2); - pfList_.remove (g1_); - pfList_.removeAndDelete (g2_); - pfList_.addShattered (g1); -} - - - -vector -ProductOperator::getValidOps (ParfactorList& pfList) -{ - vector validOps; - ParfactorList::iterator it1 = pfList.begin(); - ParfactorList::iterator penultimate = -- pfList.end(); - set pfs; - while (it1 != penultimate) { - if (Util::contains (pfs, *it1)) { - ++ it1; - continue; - } - ParfactorList::iterator it2 = it1; - ++ it2; - while (it2 != pfList.end()) { - if (Util::contains (pfs, *it2)) { - ++ it2; - continue; - } else { - if (validOp (*it1, *it2)) { - pfs.insert (*it1); - pfs.insert (*it2); - validOps.push_back (new ProductOperator ( - it1, it2, pfList)); - if (Globals::verbosity < 2) { - return validOps; - } - break; - } - } - ++ it2; - } - ++ it1; - } - return validOps; -} - - - -string -ProductOperator::toString (void) -{ - stringstream ss; - ss << "just multiplicate " ; - ss << (*g1_)->getAllGroups(); - ss << " x " ; - ss << (*g2_)->getAllGroups(); - ss << " [cost=" << std::exp (getLogCost()) << "]" << endl; - return ss.str(); -} - - - -bool -ProductOperator::validOp (Parfactor* g1, Parfactor* g2) -{ - TinySet g1_gs (g1->getAllGroups()); - TinySet g2_gs (g2->getAllGroups()); - if (g1_gs.contains (g2_gs) || g2_gs.contains (g1_gs)) { - TinySet intersect = g1_gs & g2_gs; - for (size_t i = 0; i < intersect.size(); i++) { - if (g1->nrFormulasWithGroup (intersect[i]) != 1 || - g2->nrFormulasWithGroup (intersect[i]) != 1) { - return false; - } - size_t idx1 = g1->indexOfGroup (intersect[i]); - size_t idx2 = g2->indexOfGroup (intersect[i]); - if (g1->range (idx1) != g2->range (idx2)) { - return false; - } - } - return Parfactor::canMultiply (g1, g2); - } - return false; -} - - - -double -SumOutOperator::getLogCost (void) -{ - TinySet groupSet; - ParfactorList::const_iterator pfIter = pfList_.begin(); - unsigned nrProdFactors = 0; - while (pfIter != pfList_.end()) { - if ((*pfIter)->containsGroup (group_)) { - vector groups = (*pfIter)->getAllGroups(); - groupSet |= TinySet (groups); - ++ nrProdFactors; - } - ++ pfIter; - } - if (nrProdFactors == 1) { - // best possible case - return std::log (0.0); - } - double cost = 1.0; - for (size_t i = 0; i < groupSet.size(); i++) { - pfIter = pfList_.begin(); - while (pfIter != pfList_.end()) { - if ((*pfIter)->containsGroup (groupSet[i])) { - size_t idx = (*pfIter)->indexOfGroup (groupSet[i]); - cost *= (*pfIter)->range (idx); - break; - } - ++ pfIter; - } - } - return std::log (cost); -} - - - -void -SumOutOperator::apply (void) -{ - vector iters; - iters = getParfactorsWithGroup (pfList_, group_); - Parfactor* product = *(iters[0]); - pfList_.remove (iters[0]); - for (size_t i = 1; i < iters.size(); i++) { - product->multiply (**(iters[i])); - pfList_.removeAndDelete (iters[i]); - } - if (product->nrArguments() == 1) { - delete product; - return; - } - size_t fIdx = product->indexOfGroup (group_); - LogVarSet excl = product->exclusiveLogVars (fIdx); - if (product->constr()->isCountNormalized (excl)) { - product->sumOutIndex (fIdx); - pfList_.addShattered (product); - } else { - Parfactors pfs = LiftedOperations::countNormalize (product, excl); - for (size_t i = 0; i < pfs.size(); i++) { - pfs[i]->sumOutIndex (fIdx); - pfList_.add (pfs[i]); - } - delete product; - } -} - - - -vector -SumOutOperator::getValidOps ( - ParfactorList& pfList, - const Grounds& query) -{ - vector validOps; - set allGroups; - ParfactorList::const_iterator it = pfList.begin(); - while (it != pfList.end()) { - const ProbFormulas& formulas = (*it)->arguments(); - for (size_t i = 0; i < formulas.size(); i++) { - allGroups.insert (formulas[i].group()); - } - ++ it; - } - set::const_iterator groupIt = allGroups.begin(); - while (groupIt != allGroups.end()) { - if (validOp (*groupIt, pfList, query)) { - validOps.push_back (new SumOutOperator (*groupIt, pfList)); - } - ++ groupIt; - } - return validOps; -} - - - -string -SumOutOperator::toString (void) -{ - stringstream ss; - vector pfIters; - pfIters = getParfactorsWithGroup (pfList_, group_); - size_t idx = (*pfIters[0])->indexOfGroup (group_); - ProbFormula f = (*pfIters[0])->argument (idx); - TupleSet tupleSet = (*pfIters[0])->constr()->tupleSet (f.logVars()); - ss << "sum out " << f.functor() << "/" << f.arity(); - ss << "|" << tupleSet << " (group " << group_ << ")"; - ss << " [cost=" << std::exp (getLogCost()) << "]" << endl; - return ss.str(); -} - - - -bool -SumOutOperator::validOp ( - PrvGroup group, - ParfactorList& pfList, - const Grounds& query) -{ - vector pfIters; - pfIters = getParfactorsWithGroup (pfList, group); - if (isToEliminate (*pfIters[0], group, query) == false) { - return false; - } - int range = -1; - for (size_t i = 0; i < pfIters.size(); i++) { - if ((*pfIters[i])->nrFormulasWithGroup (group) > 1) { - return false; - } - size_t fIdx = (*pfIters[i])->indexOfGroup (group); - if ((*pfIters[i])->argument (fIdx).contains ( - (*pfIters[i])->elimLogVars()) == false) { - return false; - } - if (range == -1) { - range = (*pfIters[i])->range (fIdx); - } else if ((int)(*pfIters[i])->range (fIdx) != range) { - return false; - } - } - return true; -} - - - -bool -SumOutOperator::isToEliminate ( - Parfactor* g, - PrvGroup group, - const Grounds& query) -{ - size_t fIdx = g->indexOfGroup (group); - const ProbFormula& formula = g->argument (fIdx); - bool toElim = true; - for (size_t i = 0; i < query.size(); i++) { - if (formula.functor() == query[i].functor() && - formula.arity() == query[i].arity()) { - g->constr()->moveToTop (formula.logVars()); - if (g->constr()->containsTuple (query[i].args())) { - toElim = false; - break; - } - } - } - return toElim; -} - - - -double -CountingOperator::getLogCost (void) -{ - double cost = 0.0; - size_t fIdx = (*pfIter_)->indexOfLogVar (X_); - unsigned range = (*pfIter_)->range (fIdx); - unsigned size = (*pfIter_)->size() / range; - TinySet counts; - counts = (*pfIter_)->constr()->getConditionalCounts (X_); - for (size_t i = 0; i < counts.size(); i++) { - cost += size * HistogramSet::nrHistograms (counts[i], range); - } - PrvGroup group = (*pfIter_)->argument (fIdx).group(); - size_t lvIndex = Util::indexOf ( - (*pfIter_)->argument (fIdx).logVars(), X_); - assert (lvIndex != (*pfIter_)->argument (fIdx).logVars().size()); - ParfactorList::iterator pfIter = pfList_.begin(); - while (pfIter != pfList_.end()) { - if (pfIter != pfIter_) { - size_t fIdx2 = (*pfIter)->indexOfGroup (group); - if (fIdx2 != (*pfIter)->nrArguments()) { - LogVar Y = ((*pfIter)->argument (fIdx2).logVars()[lvIndex]); - if ((*pfIter)->canCountConvert (Y) == false) { - // the real cost should be the cost of grounding Y - cost *= 10.0; - } - } - } - ++ pfIter; - } - return std::log (cost); -} - - - -void -CountingOperator::apply (void) -{ - if ((*pfIter_)->constr()->isCountNormalized (X_)) { - (*pfIter_)->countConvert (X_); - } else { - Parfactor* pf = *pfIter_; - pfList_.remove (pfIter_); - Parfactors pfs = LiftedOperations::countNormalize (pf, X_); - for (size_t i = 0; i < pfs.size(); i++) { - unsigned condCount = pfs[i]->constr()->getConditionalCount (X_); - bool cartProduct = pfs[i]->constr()->isCartesianProduct ( - pfs[i]->countedLogVars() | X_); - if (condCount > 1 && cartProduct) { - pfs[i]->countConvert (X_); - } - pfList_.add (pfs[i]); - } - delete pf; - } -} - - - -vector -CountingOperator::getValidOps (ParfactorList& pfList) -{ - vector validOps; - ParfactorList::iterator it = pfList.begin(); - while (it != pfList.end()) { - LogVarSet candidates = (*it)->uncountedLogVars(); - for (size_t i = 0; i < candidates.size(); i++) { - if (validOp (*it, candidates[i])) { - validOps.push_back (new CountingOperator ( - it, candidates[i], pfList)); - } else { - } - } - ++ it; - } - return validOps; -} - - - -string -CountingOperator::toString (void) -{ - stringstream ss; - ss << "count convert " << X_ << " in " ; - ss << (*pfIter_)->getLabel(); - ss << " [cost=" << std::exp (getLogCost()) << "]" << endl; - Parfactors pfs = LiftedOperations::countNormalize (*pfIter_, X_); - if ((*pfIter_)->constr()->isCountNormalized (X_) == false) { - for (size_t i = 0; i < pfs.size(); i++) { - ss << " º " << pfs[i]->getLabel() << endl; - } - } - for (size_t i = 0; i < pfs.size(); i++) { - delete pfs[i]; - } - return ss.str(); -} - - - -bool -CountingOperator::validOp (Parfactor* g, LogVar X) -{ - if (g->nrFormulas (X) != 1) { - return false; - } - size_t fIdx = g->indexOfLogVar (X); - if (g->argument (fIdx).isCounting()) { - return false; - } - bool countNormalized = g->constr()->isCountNormalized (X); - if (countNormalized) { - return g->canCountConvert (X); - } - return true; -} - - - -double -GroundOperator::getLogCost (void) -{ - vector> affectedFormulas; - affectedFormulas = getAffectedFormulas(); - // cout << "affected formulas: " ; - // for (size_t i = 0; i < affectedFormulas.size(); i++) { - // cout << affectedFormulas[i].first << ":" ; - // cout << affectedFormulas[i].second << " " ; - // } - // cout << "cost =" ; - double totalCost = std::log (0.0); - ParfactorList::iterator pflIt = pfList_.begin(); - while (pflIt != pfList_.end()) { - Parfactor* pf = *pflIt; - double reps = 0.0; - double pfSize = std::log (pf->size()); - bool willBeAffected = false; - LogVarSet lvsToGround; - for (size_t i = 0; i < affectedFormulas.size(); i++) { - size_t fIdx = pf->indexOfGroup (affectedFormulas[i].first); - if (fIdx != pf->nrArguments()) { - ProbFormula f = pf->argument (fIdx); - LogVar X = f.logVars()[affectedFormulas[i].second]; - bool isCountingLv = pf->countedLogVars().contains (X); - if (isCountingLv) { - unsigned nrHists = pf->range (fIdx); - unsigned nrSymbols = pf->constr()->getConditionalCount (X); - unsigned range = pf->argument (fIdx).range(); - double power = std::log (range) * nrSymbols; - pfSize = (pfSize - std::log (nrHists)) + power; - } else { - if (lvsToGround.contains (X) == false) { - reps += std::log (pf->constr()->nrSymbols (X)); - lvsToGround.insert (X); - } - } - willBeAffected = true; - } - } - if (willBeAffected) { - // cout << " + " << std::exp (reps) << "x" << std::exp (pfSize); - double pfCost = reps + pfSize; - totalCost = Util::logSum (totalCost, pfCost); - } - ++ pflIt; - } - // cout << endl; - return totalCost + 3; -} - - - -void -GroundOperator::apply (void) -{ - ParfactorList::iterator pfIter; - pfIter = getParfactorsWithGroup (pfList_, group_).front(); - Parfactor* pf = *pfIter; - size_t idx = pf->indexOfGroup (group_); - ProbFormula f = pf->argument (idx); - LogVar X = f.logVars()[lvIndex_]; - bool countedLv = pf->countedLogVars().contains (X); - pfList_.remove (pfIter); - if (countedLv) { - pf->fullExpand (X); - pfList_.add (pf); - } else { - ConstraintTrees cts = pf->constr()->ground (X); - for (size_t i = 0; i < cts.size(); i++) { - pfList_.add (new Parfactor (pf, cts[i])); - } - delete pf; - } - ParfactorList::iterator pflIt = pfList_.begin(); - while (pflIt != pfList_.end()) { - (*pflIt)->simplifyGrounds(); - ++ pflIt; - } -} - - - -vector -GroundOperator::getValidOps (ParfactorList& pfList) -{ - vector validOps; - set allGroups; - ParfactorList::const_iterator it = pfList.begin(); - while (it != pfList.end()) { - const ProbFormulas& formulas = (*it)->arguments(); - for (size_t i = 0; i < formulas.size(); i++) { - if (Util::contains (allGroups, formulas[i].group()) == false) { - const LogVars& lvs = formulas[i].logVars(); - for (size_t j = 0; j < lvs.size(); j++) { - if ((*it)->constr()->isSingleton (lvs[j]) == false) { - validOps.push_back (new GroundOperator ( - formulas[i].group(), j, pfList)); - } - } - allGroups.insert (formulas[i].group()); - } - } - ++ it; - } - return validOps; -} - - - -string -GroundOperator::toString (void) -{ - stringstream ss; - vector pfIters; - pfIters = getParfactorsWithGroup (pfList_, group_); - Parfactor* pf = *(getParfactorsWithGroup (pfList_, group_).front()); - size_t idx = pf->indexOfGroup (group_); - ProbFormula f = pf->argument (idx); - LogVar lv = f.logVars()[lvIndex_]; - TupleSet tupleSet = pf->constr()->tupleSet ({lv}); - string pos = "th"; - if (lvIndex_ == 0) { - pos = "st" ; - } else if (lvIndex_ == 1) { - pos = "nd" ; - } else if (lvIndex_ == 2) { - pos = "rd" ; - } - ss << "grounding " << lvIndex_ + 1 << pos << " log var in " ; - ss << f.functor() << "/" << f.arity(); - ss << "|" << tupleSet << " (group " << group_ << ")"; - ss << " [cost=" << std::exp (getLogCost()) << "]" << endl; - return ss.str(); -} - - - -vector> -GroundOperator::getAffectedFormulas (void) -{ - vector> affectedFormulas; - affectedFormulas.push_back (make_pair (group_, lvIndex_)); - queue> q; - q.push (make_pair (group_, lvIndex_)); - while (q.empty() == false) { - pair front = q.front(); - ParfactorList::iterator pflIt = pfList_.begin(); - while (pflIt != pfList_.end()) { - size_t idx = (*pflIt)->indexOfGroup (front.first); - if (idx != (*pflIt)->nrArguments()) { - ProbFormula f = (*pflIt)->argument (idx); - LogVar X = f.logVars()[front.second]; - const ProbFormulas& fs = (*pflIt)->arguments(); - for (size_t i = 0; i < fs.size(); i++) { - if (i != idx && fs[i].contains (X)) { - pair pair = make_pair ( - fs[i].group(), fs[i].indexOf (X)); - if (Util::contains (affectedFormulas, pair) == false) { - q.push (pair); - affectedFormulas.push_back (pair); - } - } - } - } - ++ pflIt; - } - q.pop(); - } - return affectedFormulas; -} - - - -Params -LiftedVe::solveQuery (const Grounds& query) -{ - assert (query.empty() == false); - pfList_ = parfactorList; - runSolver (query); - (*pfList_.begin())->normalize(); - Params params = (*pfList_.begin())->params(); - if (Globals::logDomain) { - Util::exp (params); - } - return params; -} - - - -void -LiftedVe::printSolverFlags (void) const -{ - stringstream ss; - ss << "lve [" ; - ss << "log_domain=" << Util::toString (Globals::logDomain); - ss << "]" ; - cout << ss.str() << endl; -} - - - -void -LiftedVe::runSolver (const Grounds& query) -{ - largestCost_ = std::log (0); - LiftedOperations::shatterAgainstQuery (pfList_, query); - LiftedOperations::runWeakBayesBall (pfList_, query); - while (true) { - if (Globals::verbosity > 2) { - Util::printDashedLine(); - pfList_.print(); - if (Globals::verbosity > 3) { - LiftedOperator::printValidOps (pfList_, query); - } - } - LiftedOperator* op = getBestOperation (query); - if (op == 0) { - break; - } - if (Globals::verbosity > 1) { - cout << "best operation: " << op->toString(); - if (Globals::verbosity > 2) { - cout << endl; - } - } - op->apply(); - delete op; - } - assert (pfList_.size() > 0); - if (pfList_.size() > 1) { - ParfactorList::iterator pfIter = pfList_.begin(); - ++ pfIter; - while (pfIter != pfList_.end()) { - (*pfList_.begin())->multiply (**pfIter); - ++ pfIter; - } - } - if (Globals::verbosity > 0) { - cout << "largest cost = " << std::exp (largestCost_) << endl; - cout << endl; - } - (*pfList_.begin())->simplifyGrounds(); - (*pfList_.begin())->reorderAccordingGrounds (query); -} - - - -LiftedOperator* -LiftedVe::getBestOperation (const Grounds& query) -{ - double bestCost = 0.0; - LiftedOperator* bestOp = 0; - vector validOps; - validOps = LiftedOperator::getValidOps (pfList_, query); - for (size_t i = 0; i < validOps.size(); i++) { - double cost = validOps[i]->getLogCost(); - if ((bestOp == 0) || (cost < bestCost)) { - bestOp = validOps[i]; - bestCost = cost; - } - } - if (bestCost > largestCost_) { - largestCost_ = bestCost; - } - for (size_t i = 0; i < validOps.size(); i++) { - if (validOps[i] != bestOp) { - delete validOps[i]; - } - } - return bestOp; -} - diff --git a/packages/CLPBN/horus2/LiftedVe.h b/packages/CLPBN/horus2/LiftedVe.h deleted file mode 100644 index 7d9974294..000000000 --- a/packages/CLPBN/horus2/LiftedVe.h +++ /dev/null @@ -1,155 +0,0 @@ -#ifndef HORUS_LIFTEDVE_H -#define HORUS_LIFTEDVE_H - -#include "LiftedSolver.h" -#include "ParfactorList.h" - - -class LiftedOperator -{ - public: - virtual ~LiftedOperator (void) { } - - virtual double getLogCost (void) = 0; - - virtual void apply (void) = 0; - - virtual string toString (void) = 0; - - static vector getValidOps ( - ParfactorList&, const Grounds&); - - static void printValidOps (ParfactorList&, const Grounds&); - - static vector getParfactorsWithGroup ( - ParfactorList&, PrvGroup group); -}; - - - -class ProductOperator : public LiftedOperator -{ - public: - ProductOperator ( - ParfactorList::iterator g1, ParfactorList::iterator g2, - ParfactorList& pfList) : g1_(g1), g2_(g2), pfList_(pfList) { } - - double getLogCost (void); - - void apply (void); - - static vector getValidOps (ParfactorList&); - - string toString (void); - - private: - static bool validOp (Parfactor*, Parfactor*); - - ParfactorList::iterator g1_; - ParfactorList::iterator g2_; - ParfactorList& pfList_; -}; - - - -class SumOutOperator : public LiftedOperator -{ - public: - SumOutOperator (PrvGroup group, ParfactorList& pfList) - : group_(group), pfList_(pfList) { } - - double getLogCost (void); - - void apply (void); - - static vector getValidOps ( - ParfactorList&, const Grounds&); - - string toString (void); - - private: - static bool validOp (PrvGroup, ParfactorList&, const Grounds&); - - static bool isToEliminate (Parfactor*, PrvGroup, const Grounds&); - - PrvGroup group_; - ParfactorList& pfList_; -}; - - - -class CountingOperator : public LiftedOperator -{ - public: - CountingOperator ( - ParfactorList::iterator pfIter, - LogVar X, - ParfactorList& pfList) - : pfIter_(pfIter), X_(X), pfList_(pfList) { } - - double getLogCost (void); - - void apply (void); - - static vector getValidOps (ParfactorList&); - - string toString (void); - - private: - static bool validOp (Parfactor*, LogVar); - - ParfactorList::iterator pfIter_; - LogVar X_; - ParfactorList& pfList_; -}; - - - -class GroundOperator : public LiftedOperator -{ - public: - GroundOperator ( - PrvGroup group, - unsigned lvIndex, - ParfactorList& pfList) - : group_(group), lvIndex_(lvIndex), pfList_(pfList) { } - - double getLogCost (void); - - void apply (void); - - static vector getValidOps (ParfactorList&); - - string toString (void); - - private: - vector> getAffectedFormulas (void); - - PrvGroup group_; - unsigned lvIndex_; - ParfactorList& pfList_; -}; - - - -class LiftedVe : public LiftedSolver -{ - public: - LiftedVe (const ParfactorList& pfList) - : LiftedSolver(pfList) { } - - Params solveQuery (const Grounds&); - - void printSolverFlags (void) const; - - private: - void runSolver (const Grounds&); - - LiftedOperator* getBestOperation (const Grounds&); - - ParfactorList pfList_; - double largestCost_; -}; - -#endif // HORUS_LIFTEDVE_H - diff --git a/packages/CLPBN/horus2/LiftedWCNF.cpp b/packages/CLPBN/horus2/LiftedWCNF.cpp deleted file mode 100644 index ba7097dbf..000000000 --- a/packages/CLPBN/horus2/LiftedWCNF.cpp +++ /dev/null @@ -1,658 +0,0 @@ -#include "LiftedWCNF.h" -#include "ConstraintTree.h" -#include "Indexer.h" - - - -bool -Literal::isGround (ConstraintTree constr, LogVarSet ipgLogVars) const -{ - if (logVars_.size() == 0) { - return true; - } - LogVarSet lvs (logVars_); - lvs -= ipgLogVars; - return constr.singletons().contains (lvs); -} - - - -size_t -Literal::indexOfLogVar (LogVar X) const -{ - return Util::indexOf (logVars_, X); -} - - - -string -Literal::toString ( - LogVarSet ipgLogVars, - LogVarSet posCountedLvs, - LogVarSet negCountedLvs) const -{ - stringstream ss; - negated_ ? ss << "¬" : ss << "" ; - ss << "λ" ; - ss << lid_ ; - if (logVars_.empty() == false) { - ss << "(" ; - for (size_t i = 0; i < logVars_.size(); i++) { - if (i != 0) ss << ","; - if (posCountedLvs.contains (logVars_[i])) { - ss << "+" << logVars_[i]; - } else if (negCountedLvs.contains (logVars_[i])) { - ss << "-" << logVars_[i]; - } else if (ipgLogVars.contains (logVars_[i])) { - LogVar X = logVars_[i]; - const string labels[] = { - "a", "b", "c", "d", "e", "f", - "g", "h", "i", "j", "k", "m" }; - (X >= 12) ? ss << "x_" << X : ss << labels[X]; - } else { - ss << logVars_[i]; - } - } - ss << ")" ; - } - return ss.str(); -} - - - -std::ostream& -operator<< (ostream &os, const Literal& lit) -{ - os << lit.toString(); - return os; -} - - - -void -Clause::addLiteralComplemented (const Literal& lit) -{ - assert (constr_.logVarSet().contains (lit.logVars())); - literals_.push_back (lit); - literals_.back().complement(); -} - - - -bool -Clause::containsLiteral (LiteralId lid) const -{ - for (size_t i = 0; i < literals_.size(); i++) { - if (literals_[i].lid() == lid) { - return true; - } - } - return false; -} - - - -bool -Clause::containsPositiveLiteral ( - LiteralId lid, - const LogVarTypes& types) const -{ - for (size_t i = 0; i < literals_.size(); i++) { - if (literals_[i].lid() == lid - && literals_[i].isPositive() - && logVarTypes (i) == types) { - return true; - } - } - return false; -} - - - -bool -Clause::containsNegativeLiteral ( - LiteralId lid, - const LogVarTypes& types) const -{ - for (size_t i = 0; i < literals_.size(); i++) { - if (literals_[i].lid() == lid - && literals_[i].isNegative() - && logVarTypes (i) == types) { - return true; - } - } - return false; -} - - - -void -Clause::removeLiterals (LiteralId lid) -{ - size_t i = 0; - while (i != literals_.size()) { - if (literals_[i].lid() == lid) { - removeLiteral (i); - } else { - i ++; - } - } -} - - - -void -Clause::removePositiveLiterals ( - LiteralId lid, - const LogVarTypes& types) -{ - size_t i = 0; - while (i != literals_.size()) { - if (literals_[i].lid() == lid - && literals_[i].isPositive() - && logVarTypes (i) == types) { - removeLiteral (i); - } else { - i ++; - } - } -} - - - -void -Clause::removeNegativeLiterals ( - LiteralId lid, - const LogVarTypes& types) -{ - size_t i = 0; - while (i != literals_.size()) { - if (literals_[i].lid() == lid - && literals_[i].isNegative() - && logVarTypes (i) == types) { - removeLiteral (i); - } else { - i ++; - } - } -} - - - -bool -Clause::isCountedLogVar (LogVar X) const -{ - assert (constr_.logVarSet().contains (X)); - return posCountedLvs_.contains (X) - || negCountedLvs_.contains (X); -} - - - -bool -Clause::isPositiveCountedLogVar (LogVar X) const -{ - assert (constr_.logVarSet().contains (X)); - return posCountedLvs_.contains (X); -} - - - -bool -Clause::isNegativeCountedLogVar (LogVar X) const -{ - assert (constr_.logVarSet().contains (X)); - return negCountedLvs_.contains (X); -} - - - -bool -Clause::isIpgLogVar (LogVar X) const -{ - assert (constr_.logVarSet().contains (X)); - return ipgLvs_.contains (X); -} - - - -TinySet -Clause::lidSet (void) const -{ - TinySet lidSet; - for (size_t i = 0; i < literals_.size(); i++) { - lidSet.insert (literals_[i].lid()); - } - return lidSet; -} - - - -LogVarSet -Clause::ipgCandidates (void) const -{ - LogVarSet candidates; - LogVarSet allLvs = constr_.logVarSet(); - allLvs -= ipgLvs_; - allLvs -= posCountedLvs_; - allLvs -= negCountedLvs_; - for (size_t i = 0; i < allLvs.size(); i++) { - bool valid = true; - for (size_t j = 0; j < literals_.size(); j++) { - if (Util::contains (literals_[j].logVars(), allLvs[i]) == false) { - valid = false; - break; - } - } - if (valid) { - candidates.insert (allLvs[i]); - } - } - return candidates; -} - - - -LogVarTypes -Clause::logVarTypes (size_t litIdx) const -{ - LogVarTypes types; - const LogVars& lvs = literals_[litIdx].logVars(); - for (size_t i = 0; i < lvs.size(); i++) { - if (posCountedLvs_.contains (lvs[i])) { - types.push_back (LogVarType::POS_LV); - } else if (negCountedLvs_.contains (lvs[i])) { - types.push_back (LogVarType::NEG_LV); - } else { - types.push_back (LogVarType::FULL_LV); - } - } - return types; -} - - - -void -Clause::removeLiteral (size_t litIdx) -{ - LogVarSet lvsToRemove = literals_[litIdx].logVarSet() - - getLogVarSetExcluding (litIdx); - ipgLvs_ -= lvsToRemove; - posCountedLvs_ -= lvsToRemove; - negCountedLvs_ -= lvsToRemove; - constr_.remove (lvsToRemove); - literals_.erase (literals_.begin() + litIdx); -} - - - -bool -Clause::independentClauses (Clause& c1, Clause& c2) -{ - const Literals& lits1 = c1.literals(); - const Literals& lits2 = c2.literals(); - for (size_t i = 0; i < lits1.size(); i++) { - for (size_t j = 0; j < lits2.size(); j++) { - if (lits1[i].lid() == lits2[j].lid() - && c1.logVarTypes (i) == c2.logVarTypes (j)) { - return false; - } - } - } - return true; -} - - - -Clauses -Clause::copyClauses (const Clauses& clauses) -{ - Clauses copy; - copy.reserve (clauses.size()); - for (size_t i = 0; i < clauses.size(); i++) { - copy.push_back (new Clause (*clauses[i])); - } - return copy; -} - - - -void -Clause::printClauses (const Clauses& clauses) -{ - for (size_t i = 0; i < clauses.size(); i++) { - cout << *clauses[i] << endl; - } -} - - - -void -Clause::deleteClauses (Clauses& clauses) -{ - for (size_t i = 0; i < clauses.size(); i++) { - delete clauses[i]; - } -} - - - -std::ostream& -operator<< (ostream &os, const Clause& clause) -{ - for (unsigned i = 0; i < clause.literals_.size(); i++) { - if (i != 0) os << " v " ; - os << clause.literals_[i].toString (clause.ipgLvs_, - clause.posCountedLvs_, clause.negCountedLvs_); - } - if (clause.constr_.empty() == false) { - ConstraintTree copy (clause.constr_); - copy.moveToTop (copy.logVarSet().elements()); - os << " | " << copy.tupleSet(); - } - return os; -} - - - -LogVarSet -Clause::getLogVarSetExcluding (size_t idx) const -{ - LogVarSet lvs; - for (size_t i = 0; i < literals_.size(); i++) { - if (i != idx) { - lvs |= literals_[i].logVars(); - } - } - return lvs; -} - - - -std::ostream& -operator<< (std::ostream &os, const LitLvTypes& lit) -{ - os << lit.lid_ << "<" ; - for (size_t i = 0; i < lit.lvTypes_.size(); i++) { - switch (lit.lvTypes_[i]) { - case LogVarType::FULL_LV: os << "F" ; break; - case LogVarType::POS_LV: os << "P" ; break; - case LogVarType::NEG_LV: os << "N" ; break; - } - } - os << ">" ; - return os; -} - - - -LiftedWCNF::LiftedWCNF (const ParfactorList& pfList) - : freeLiteralId_(0), pfList_(pfList) -{ - addIndicatorClauses (pfList); - addParameterClauses (pfList); - - /* - // INCLUSION-EXCLUSION TEST - clauses_.clear(); - vector> names = { - {"a1","b1"},{"a2","b2"} - }; - Clause* c1 = new Clause (names); - c1->addLiteral (Literal (0, LogVars() = {0})); - c1->addLiteral (Literal (1, LogVars() = {1})); - clauses_.push_back(c1); - */ - - /* - // INDEPENDENT PARTIAL GROUND TEST - clauses_.clear(); - vector> names = { - {"a1","b1"},{"a2","b2"} - }; - Clause* c1 = new Clause (names); - c1->addLiteral (Literal (0, LogVars() = {0,1})); - c1->addLiteral (Literal (1, LogVars() = {0,1})); - clauses_.push_back(c1); - Clause* c2 = new Clause (names); - c2->addLiteral (Literal (2, LogVars() = {0})); - c2->addLiteral (Literal (1, LogVars() = {0,1})); - clauses_.push_back(c2); - */ - - /* - // ATOM-COUNTING TEST - clauses_.clear(); - vector> names = { - {"p1","p1"},{"p1","p2"},{"p1","p3"}, - {"p2","p1"},{"p2","p2"},{"p2","p3"}, - {"p3","p1"},{"p3","p2"},{"p3","p3"} - }; - Clause* c1 = new Clause (names); - c1->addLiteral (Literal (0, LogVars() = {0})); - c1->addLiteralComplemented (Literal (1, {0,1})); - clauses_.push_back(c1); - Clause* c2 = new Clause (names); - c2->addLiteral (Literal (0, LogVars()={0})); - c2->addLiteralComplemented (Literal (1, {1,0})); - clauses_.push_back(c2); - */ - - if (Globals::verbosity > 1) { - cout << "FORMULA INDICATORS:" << endl; - printFormulaIndicators(); - cout << endl; - cout << "WEIGHTED INDICATORS:" << endl; - printWeights(); - cout << endl; - cout << "CLAUSES:" << endl; - printClauses(); - cout << endl; - } -} - - - -LiftedWCNF::~LiftedWCNF (void) -{ - Clause::deleteClauses (clauses_); -} - - - -void -LiftedWCNF::addWeight (LiteralId lid, double posW, double negW) -{ - weights_[lid] = make_pair (posW, negW); -} - - - -double -LiftedWCNF::posWeight (LiteralId lid) const -{ - unordered_map>::const_iterator it; - it = weights_.find (lid); - return it != weights_.end() ? it->second.first : LogAware::one(); -} - - - -double -LiftedWCNF::negWeight (LiteralId lid) const -{ - unordered_map>::const_iterator it; - it = weights_.find (lid); - return it != weights_.end() ? it->second.second : LogAware::one(); -} - - - -vector -LiftedWCNF::prvGroupLiterals (PrvGroup prvGroup) -{ - assert (Util::contains (map_, prvGroup)); - return map_[prvGroup]; -} - - - -Clause* -LiftedWCNF::createClause (LiteralId lid) const -{ - for (size_t i = 0; i < clauses_.size(); i++) { - const Literals& literals = clauses_[i]->literals(); - for (size_t j = 0; j < literals.size(); j++) { - if (literals[j].lid() == lid) { - ConstraintTree ct = clauses_[i]->constr().projectedCopy ( - literals[j].logVars()); - Clause* c = new Clause (ct); - c->addLiteral (literals[j]); - return c; - } - } - } - return 0; -} - - - -LiteralId -LiftedWCNF::getLiteralId (PrvGroup prvGroup, unsigned range) -{ - assert (Util::contains (map_, prvGroup)); - return map_[prvGroup][range]; -} - - - -void -LiftedWCNF::addIndicatorClauses (const ParfactorList& pfList) -{ - ParfactorList::const_iterator it = pfList.begin(); - while (it != pfList.end()) { - const ProbFormulas& formulas = (*it)->arguments(); - for (size_t i = 0; i < formulas.size(); i++) { - if (Util::contains (map_, formulas[i].group()) == false) { - ConstraintTree tempConstr = (*it)->constr()->projectedCopy( - formulas[i].logVars()); - Clause* clause = new Clause (tempConstr); - vector lids; - for (size_t j = 0; j < formulas[i].range(); j++) { - clause->addLiteral (Literal (freeLiteralId_, formulas[i].logVars())); - lids.push_back (freeLiteralId_); - freeLiteralId_ ++; - } - clauses_.push_back (clause); - for (size_t j = 0; j < formulas[i].range() - 1; j++) { - for (size_t k = j + 1; k < formulas[i].range(); k++) { - ConstraintTree tempConstr2 = (*it)->constr()->projectedCopy ( - formulas[i].logVars()); - Clause* clause2 = new Clause (tempConstr2); - clause2->addLiteralComplemented (Literal (clause->literals()[j])); - clause2->addLiteralComplemented (Literal (clause->literals()[k])); - clauses_.push_back (clause2); - } - } - map_[formulas[i].group()] = lids; - } - } - ++ it; - } -} - - - -void -LiftedWCNF::addParameterClauses (const ParfactorList& pfList) -{ - ParfactorList::const_iterator it = pfList.begin(); - while (it != pfList.end()) { - Indexer indexer ((*it)->ranges()); - vector groups = (*it)->getAllGroups(); - while (indexer.valid()) { - LiteralId paramVarLid = freeLiteralId_; - // λu1 ∧ ... ∧ λun ∧ λxi <=> θxi|u1,...,un - // - // ¬λu1 ... ¬λun v θxi|u1,...,un -> clause1 - // ¬θxi|u1,...,un v λu1 -> tempClause - // ¬θxi|u1,...,un v λu2 -> tempClause - double posWeight = (**it)[indexer]; - addWeight (paramVarLid, posWeight, LogAware::one()); - - Clause* clause1 = new Clause (*(*it)->constr()); - - for (unsigned i = 0; i < groups.size(); i++) { - LiteralId lid = getLiteralId (groups[i], indexer[i]); - - clause1->addLiteralComplemented ( - Literal (lid, (*it)->argument(i).logVars())); - - ConstraintTree ct = *(*it)->constr(); - Clause* tempClause = new Clause (ct); - tempClause->addLiteralComplemented (Literal ( - paramVarLid, (*it)->constr()->logVars())); - tempClause->addLiteral (Literal (lid, (*it)->argument(i).logVars())); - clauses_.push_back (tempClause); - } - clause1->addLiteral (Literal (paramVarLid, (*it)->constr()->logVars())); - clauses_.push_back (clause1); - freeLiteralId_ ++; - ++ indexer; - } - ++ it; - } -} - - - -void -LiftedWCNF::printFormulaIndicators (void) const -{ - if (map_.empty()) { - return; - } - set allGroups; - ParfactorList::const_iterator it = pfList_.begin(); - while (it != pfList_.end()) { - const ProbFormulas& formulas = (*it)->arguments(); - for (size_t i = 0; i < formulas.size(); i++) { - if (Util::contains (allGroups, formulas[i].group()) == false) { - allGroups.insert (formulas[i].group()); - cout << formulas[i] << " | " ; - ConstraintTree tempCt = (*it)->constr()->projectedCopy ( - formulas[i].logVars()); - cout << tempCt.tupleSet(); - cout << " indicators => " ; - vector indicators = - (map_.find (formulas[i].group()))->second; - cout << indicators << endl; - } - } - ++ it; - } -} - - - -void -LiftedWCNF::printWeights (void) const -{ - unordered_map>::const_iterator it; - it = weights_.begin(); - while (it != weights_.end()) { - cout << "λ" << it->first << " weights: " ; - cout << it->second.first << " " << it->second.second; - cout << endl; - ++ it; - } -} - - - -void -LiftedWCNF::printClauses (void) const -{ - Clause::printClauses (clauses_); -} - diff --git a/packages/CLPBN/horus2/LiftedWCNF.h b/packages/CLPBN/horus2/LiftedWCNF.h deleted file mode 100644 index e0f901b7c..000000000 --- a/packages/CLPBN/horus2/LiftedWCNF.h +++ /dev/null @@ -1,239 +0,0 @@ -#ifndef HORUS_LIFTEDWCNF_H -#define HORUS_LIFTEDWCNF_H - -#include "ParfactorList.h" - -using namespace std; - -typedef long LiteralId; - -class ConstraintTree; - - -enum LogVarType -{ - FULL_LV, - POS_LV, - NEG_LV -}; - -typedef vector LogVarTypes; - - - -class Literal -{ - public: - Literal (LiteralId lid, const LogVars& lvs) : - lid_(lid), logVars_(lvs), negated_(false) { } - - Literal (const Literal& lit, bool negated) : - lid_(lit.lid_), logVars_(lit.logVars_), negated_(negated) { } - - LiteralId lid (void) const { return lid_; } - - LogVars logVars (void) const { return logVars_; } - - size_t nrLogVars (void) const { return logVars_.size(); } - - LogVarSet logVarSet (void) const { return LogVarSet (logVars_); } - - void complement (void) { negated_ = !negated_; } - - bool isPositive (void) const { return negated_ == false; } - - bool isNegative (void) const { return negated_; } - - bool isGround (ConstraintTree constr, LogVarSet ipgLogVars) const; - - size_t indexOfLogVar (LogVar X) const; - - string toString (LogVarSet ipgLogVars = LogVarSet(), - LogVarSet posCountedLvs = LogVarSet(), - LogVarSet negCountedLvs = LogVarSet()) const; - - friend std::ostream& operator<< (std::ostream &os, const Literal& lit); - - private: - LiteralId lid_; - LogVars logVars_; - bool negated_; -}; - -typedef vector Literals; - - - -class Clause -{ - public: - Clause (const ConstraintTree& ct = ConstraintTree({})) : constr_(ct) { } - - Clause (vector> names) : constr_(ConstraintTree (names)) { } - - void addLiteral (const Literal& l) { literals_.push_back (l); } - - const Literals& literals (void) const { return literals_; } - - Literals& literals (void) { return literals_; } - - size_t nrLiterals (void) const { return literals_.size(); } - - const ConstraintTree& constr (void) const { return constr_; } - - ConstraintTree constr (void) { return constr_; } - - bool isUnit (void) const { return literals_.size() == 1; } - - LogVarSet ipgLogVars (void) const { return ipgLvs_; } - - void addIpgLogVar (LogVar X) { ipgLvs_.insert (X); } - - void addPosCountedLogVar (LogVar X) { posCountedLvs_.insert (X); } - - void addNegCountedLogVar (LogVar X) { negCountedLvs_.insert (X); } - - LogVarSet posCountedLogVars (void) const { return posCountedLvs_; } - - LogVarSet negCountedLogVars (void) const { return negCountedLvs_; } - - unsigned nrPosCountedLogVars (void) const { return posCountedLvs_.size(); } - - unsigned nrNegCountedLogVars (void) const { return negCountedLvs_.size(); } - - void addLiteralComplemented (const Literal& lit); - - bool containsLiteral (LiteralId lid) const; - - bool containsPositiveLiteral (LiteralId lid, const LogVarTypes&) const; - - bool containsNegativeLiteral (LiteralId lid, const LogVarTypes&) const; - - void removeLiterals (LiteralId lid); - - void removePositiveLiterals (LiteralId lid, const LogVarTypes&); - - void removeNegativeLiterals (LiteralId lid, const LogVarTypes&); - - bool isCountedLogVar (LogVar X) const; - - bool isPositiveCountedLogVar (LogVar X) const; - - bool isNegativeCountedLogVar (LogVar X) const; - - bool isIpgLogVar (LogVar X) const; - - TinySet lidSet (void) const; - - LogVarSet ipgCandidates (void) const; - - LogVarTypes logVarTypes (size_t litIdx) const; - - void removeLiteral (size_t litIdx); - - static bool independentClauses (Clause& c1, Clause& c2); - - static vector copyClauses (const vector& clauses); - - static void printClauses (const vector& clauses); - - static void deleteClauses (vector& clauses); - - friend std::ostream& operator<< (ostream &os, const Clause& clause); - - private: - LogVarSet getLogVarSetExcluding (size_t idx) const; - - Literals literals_; - LogVarSet ipgLvs_; - LogVarSet posCountedLvs_; - LogVarSet negCountedLvs_; - ConstraintTree constr_; -}; - -typedef vector Clauses; - - - -class LitLvTypes -{ - public: - struct CompareLitLvTypes - { - bool operator() ( - const LitLvTypes& types1, - const LitLvTypes& types2) const - { - if (types1.lid_ < types2.lid_) { - return true; - } - if (types1.lid_ == types2.lid_) { - return types1.lvTypes_ < types2.lvTypes_; - } - return false; - } - }; - - LitLvTypes (LiteralId lid, const LogVarTypes& lvTypes) : - lid_(lid), lvTypes_(lvTypes) { } - - LiteralId lid (void) const { return lid_; } - - const LogVarTypes& logVarTypes (void) const { return lvTypes_; } - - void setAllFullLogVars (void) { - std::fill (lvTypes_.begin(), lvTypes_.end(), LogVarType::FULL_LV); } - - friend std::ostream& operator<< (std::ostream &os, const LitLvTypes& lit); - - private: - LiteralId lid_; - LogVarTypes lvTypes_; -}; - -typedef TinySet LitLvTypesSet; - - - -class LiftedWCNF -{ - public: - LiftedWCNF (const ParfactorList& pfList); - - ~LiftedWCNF (void); - - const Clauses& clauses (void) const { return clauses_; } - - void addWeight (LiteralId lid, double posW, double negW); - - double posWeight (LiteralId lid) const; - - double negWeight (LiteralId lid) const; - - vector prvGroupLiterals (PrvGroup prvGroup); - - Clause* createClause (LiteralId lid) const; - - void printFormulaIndicators (void) const; - - void printWeights (void) const; - - void printClauses (void) const; - - private: - - LiteralId getLiteralId (PrvGroup prvGroup, unsigned range); - - void addIndicatorClauses (const ParfactorList& pfList); - - void addParameterClauses (const ParfactorList& pfList); - - Clauses clauses_; - LiteralId freeLiteralId_; - const ParfactorList& pfList_; - unordered_map> map_; - unordered_map> weights_; -}; - -#endif // HORUS_LIFTEDWCNF_H - diff --git a/packages/CLPBN/horus2/Parfactor.cpp b/packages/CLPBN/horus2/Parfactor.cpp deleted file mode 100644 index ef2301b7b..000000000 --- a/packages/CLPBN/horus2/Parfactor.cpp +++ /dev/null @@ -1,942 +0,0 @@ - -#include "Parfactor.h" -#include "Histogram.h" -#include "Indexer.h" -#include "Util.h" -#include "Horus.h" - - -Parfactor::Parfactor ( - const ProbFormulas& formulas, - const Params& params, - const Tuples& tuples, - unsigned distId) -{ - args_ = formulas; - params_ = params; - distId_ = distId; - - LogVars logVars; - for (size_t i = 0; i < args_.size(); i++) { - ranges_.push_back (args_[i].range()); - const LogVars& lvs = args_[i].logVars(); - for (size_t j = 0; j < lvs.size(); j++) { - if (Util::contains (logVars, lvs[j]) == false) { - logVars.push_back (lvs[j]); - } - } - } - LogVar newLv = logVars.size(); - constr_ = new ConstraintTree (logVars, tuples); - // Change formulas like f(X,X), X in {(p1),(p2),...} - // to be like f(X,Y), (X,Y) in {(p1,p1),(p2,p2),...}. - // This will simplify shattering on the constraint tree. - for (size_t i = 0; i < args_.size(); i++) { - LogVarSet lvSet; - LogVars& lvs = args_[i].logVars(); - for (size_t j = 0; j < lvs.size(); j++) { - if (lvSet.contains (lvs[j]) == false) { - lvSet |= lvs[j]; - } else { - constr_->cloneLogVar (lvs[j], newLv); - lvs[j] = newLv; - ++ newLv; - } - } - } - assert (params_.size() == Util::sizeExpected (ranges_)); -} - - - -Parfactor::Parfactor (const Parfactor* g, const Tuple& tuple) -{ - args_ = g->arguments(); - params_ = g->params(); - ranges_ = g->ranges(); - distId_ = g->distId(); - constr_ = new ConstraintTree (g->logVars(), {tuple}); - assert (params_.size() == Util::sizeExpected (ranges_)); -} - - - -Parfactor::Parfactor (const Parfactor* g, ConstraintTree* constr) -{ - args_ = g->arguments(); - params_ = g->params(); - ranges_ = g->ranges(); - distId_ = g->distId(); - constr_ = constr; - assert (params_.size() == Util::sizeExpected (ranges_)); -} - - - -Parfactor::Parfactor (const Parfactor& g) -{ - args_ = g.arguments(); - params_ = g.params(); - ranges_ = g.ranges(); - distId_ = g.distId(); - constr_ = new ConstraintTree (*g.constr()); - assert (params_.size() == Util::sizeExpected (ranges_)); -} - - - -Parfactor::~Parfactor (void) -{ - delete constr_; -} - - - -LogVarSet -Parfactor::countedLogVars (void) const -{ - LogVarSet set; - for (size_t i = 0; i < args_.size(); i++) { - if (args_[i].isCounting()) { - set.insert (args_[i].countedLogVar()); - } - } - return set; -} - - - -LogVarSet -Parfactor::uncountedLogVars (void) const -{ - return constr_->logVarSet() - countedLogVars(); -} - - - -LogVarSet -Parfactor::elimLogVars (void) const -{ - LogVarSet requiredToElim = constr_->logVarSet(); - requiredToElim -= constr_->singletons(); - requiredToElim -= countedLogVars(); - return requiredToElim; -} - - - -LogVarSet -Parfactor::exclusiveLogVars (size_t fIdx) const -{ - assert (fIdx < args_.size()); - LogVarSet remaining; - for (size_t i = 0; i < args_.size(); i++) { - if (i != fIdx) { - remaining |= args_[i].logVarSet(); - } - } - return args_[fIdx].logVarSet() - remaining; -} - - - -void -Parfactor::sumOutIndex (size_t fIdx) -{ - assert (fIdx < args_.size()); - assert (args_[fIdx].contains (elimLogVars())); - - if (args_[fIdx].isCounting()) { - unsigned N = constr_->getConditionalCount ( - args_[fIdx].countedLogVar()); - unsigned R = args_[fIdx].range(); - vector numAssigns = HistogramSet::getNumAssigns (N, R); - Indexer indexer (ranges_, fIdx); - while (indexer.valid()) { - if (Globals::logDomain) { - params_[indexer] += numAssigns[ indexer[fIdx] ]; - } else { - params_[indexer] *= numAssigns[ indexer[fIdx] ]; - } - ++ indexer; - } - } - - LogVarSet excl = exclusiveLogVars (fIdx); - unsigned exp; - if (args_[fIdx].isCounting()) { - // counting log vars were already raised on counting conversion - exp = constr_->getConditionalCount (excl - args_[fIdx].countedLogVar()); - } else { - exp = constr_->getConditionalCount (excl); - } - constr_->remove (excl); - - TFactor::sumOutIndex (fIdx); - LogAware::pow (params_, exp); -} - - - -void -Parfactor::multiply (Parfactor& g) -{ - alignAndExponentiate (this, &g); - TFactor::multiply (g); - constr_->join (g.constr(), true); - simplifyGrounds(); - assert (constr_->isCartesianProduct (countedLogVars())); -} - - - -bool -Parfactor::canCountConvert (LogVar X) -{ - if (nrFormulas (X) != 1) { - return false; - } - size_t fIdx = indexOfLogVar (X); - if (args_[fIdx].isCounting()) { - return false; - } - if (constr_->isCountNormalized (X) == false) { - return false; - } - if (constr_->getConditionalCount (X) == 1) { - return false; - } - if (constr_->isCartesianProduct (countedLogVars() | X) == false) { - return false; - } - return true; -} - - - -void -Parfactor::countConvert (LogVar X) -{ - size_t fIdx = indexOfLogVar (X); - assert (constr_->isCountNormalized (X)); - assert (constr_->getConditionalCount (X) > 1); - assert (canCountConvert (X)); - - unsigned N = constr_->getConditionalCount (X); - unsigned R = ranges_[fIdx]; - unsigned H = HistogramSet::nrHistograms (N, R); - vector histograms = HistogramSet::getHistograms (N, R); - - Indexer indexer (ranges_); - vector sumout (params_.size() / R); - unsigned count = 0; - while (indexer.valid()) { - sumout[count].reserve (R); - for (unsigned r = 0; r < R; r++) { - sumout[count].push_back (params_[indexer]); - indexer.incrementDimension (fIdx); - } - count ++; - indexer.resetDimension (fIdx); - indexer.incrementExceptDimension (fIdx); - } - - params_.clear(); - params_.reserve (sumout.size() * H); - - ranges_[fIdx] = H; - MapIndexer mapIndexer (ranges_, fIdx); - while (mapIndexer.valid()) { - double prod = LogAware::multIdenty(); - size_t i = mapIndexer; - unsigned h = mapIndexer[fIdx]; - for (unsigned r = 0; r < R; r++) { - if (Globals::logDomain) { - prod += LogAware::pow (sumout[i][r], histograms[h][r]); - } else { - prod *= LogAware::pow (sumout[i][r], histograms[h][r]); - } - } - params_.push_back (prod); - ++ mapIndexer; - } - args_[fIdx].setCountedLogVar (X); - simplifyCountingFormulas (fIdx); -} - - - -void -Parfactor::expand (LogVar X, LogVar X_new1, LogVar X_new2) -{ - size_t fIdx = indexOfLogVar (X); - assert (fIdx != args_.size()); - assert (args_[fIdx].isCounting()); - - unsigned N1 = constr_->getConditionalCount (X_new1); - unsigned N2 = constr_->getConditionalCount (X_new2); - unsigned N = N1 + N2; - unsigned R = args_[fIdx].range(); - unsigned H1 = HistogramSet::nrHistograms (N1, R); - unsigned H2 = HistogramSet::nrHistograms (N2, R); - - vector histograms = HistogramSet::getHistograms (N, R); - vector histograms1 = HistogramSet::getHistograms (N1, R); - vector histograms2 = HistogramSet::getHistograms (N2, R); - - vector sumIndexes; - sumIndexes.reserve (H1 * H2); - for (unsigned i = 0; i < H1; i++) { - for (unsigned j = 0; j < H2; j++) { - Histogram hist = histograms1[i]; - hist += histograms2[j]; - sumIndexes.push_back (HistogramSet::findIndex (hist, histograms)); - } - } - - expandPotential (fIdx, H1 * H2, sumIndexes); - - args_.insert (args_.begin() + fIdx + 1, args_[fIdx]); - args_[fIdx].rename (X, X_new1); - args_[fIdx + 1].rename (X, X_new2); - if (H1 == 2) { - args_[fIdx].clearCountedLogVar(); - } - if (H2 == 2) { - args_[fIdx + 1].clearCountedLogVar(); - } - ranges_.insert (ranges_.begin() + fIdx + 1, H2); - ranges_[fIdx] = H1; -} - - - -void -Parfactor::fullExpand (LogVar X) -{ - size_t fIdx = indexOfLogVar (X); - assert (fIdx != args_.size()); - assert (args_[fIdx].isCounting()); - - unsigned N = constr_->getConditionalCount (X); - unsigned R = args_[fIdx].range(); - vector originHists = HistogramSet::getHistograms (N, R); - vector expandHists = HistogramSet::getHistograms (1, R); - assert (ranges_[fIdx] == originHists.size()); - vector sumIndexes; - sumIndexes.reserve (N * R); - - Ranges expandRanges (N, R); - Indexer indexer (expandRanges); - while (indexer.valid()) { - vector hist (R, 0); - for (unsigned n = 0; n < N; n++) { - hist += expandHists[indexer[n]]; - } - sumIndexes.push_back (HistogramSet::findIndex (hist, originHists)); - ++ indexer; - } - - expandPotential (fIdx, std::pow (R, N), sumIndexes); - - ProbFormula f = args_[fIdx]; - args_.erase (args_.begin() + fIdx); - ranges_.erase (ranges_.begin() + fIdx); - LogVars newLvs = constr_->expand (X); - assert (newLvs.size() == N); - for (unsigned i = 0 ; i < N; i++) { - ProbFormula newFormula (f.functor(), f.logVars(), f.range()); - newFormula.rename (X, newLvs[i]); - args_.insert (args_.begin() + fIdx + i, newFormula); - ranges_.insert (ranges_.begin() + fIdx + i, R); - } -} - - - -void -Parfactor::reorderAccordingGrounds (const Grounds& grounds) -{ - ProbFormulas newFormulas; - for (size_t i = 0; i < grounds.size(); i++) { - for (size_t j = 0; j < args_.size(); j++) { - if (grounds[i].functor() == args_[j].functor() && - grounds[i].arity() == args_[j].arity()) { - constr_->moveToTop (args_[j].logVars()); - if (constr_->containsTuple (grounds[i].args())) { - newFormulas.push_back (args_[j]); - break; - } - } - } - assert (newFormulas.size() == i + 1); - } - reorderArguments (newFormulas); -} - - - -void -Parfactor::absorveEvidence (const ProbFormula& formula, unsigned evidence) -{ - size_t fIdx = indexOf (formula); - assert (fIdx != args_.size()); - LogVarSet excl = exclusiveLogVars (fIdx); - assert (args_[fIdx].isCounting() == false); - assert (constr_->isCountNormalized (excl)); - LogAware::pow (params_, constr_->getConditionalCount (excl)); - TFactor::absorveEvidence (formula, evidence); - constr_->remove (excl); -} - - - -void -Parfactor::setNewGroups (void) -{ - for (size_t i = 0; i < args_.size(); i++) { - args_[i].setGroup (ProbFormula::getNewGroup()); - } -} - - - -void -Parfactor::applySubstitution (const Substitution& theta) -{ - for (size_t i = 0; i < args_.size(); i++) { - LogVars& lvs = args_[i].logVars(); - for (size_t j = 0; j < lvs.size(); j++) { - lvs[j] = theta.newNameFor (lvs[j]); - } - if (args_[i].isCounting()) { - LogVar clv = args_[i].countedLogVar(); - args_[i].setCountedLogVar (theta.newNameFor (clv)); - } - } - constr_->applySubstitution (theta); -} - - - -size_t -Parfactor::indexOfGround (const Ground& ground) const -{ - size_t idx = args_.size(); - for (size_t i = 0; i < args_.size(); i++) { - if (args_[i].functor() == ground.functor() && - args_[i].arity() == ground.arity()) { - constr_->moveToTop (args_[i].logVars()); - if (constr_->containsTuple (ground.args())) { - idx = i; - break; - } - } - } - return idx; -} - - - -PrvGroup -Parfactor::findGroup (const Ground& ground) const -{ - size_t idx = indexOfGround (ground); - return idx == args_.size() - ? numeric_limits::max() - : args_[idx].group(); -} - - - -bool -Parfactor::containsGround (const Ground& ground) const -{ - return findGroup (ground) != numeric_limits::max(); -} - - - -bool -Parfactor::containsGrounds (const Grounds& grounds) const -{ - Tuple tuple; - LogVars tupleLvs; - for (size_t i = 0; i < grounds.size(); i++) { - size_t idx = indexOfGround (grounds[i]); - if (idx == args_.size()) { - return false; - } - LogVars lvs = args_[idx].logVars(); - for (size_t j = 0; j < lvs.size(); j++) { - if (Util::contains (tupleLvs, lvs[j]) == false) { - tuple.push_back (grounds[i].args()[j]); - tupleLvs.push_back (lvs[j]); - } - } - } - constr_->moveToTop (tupleLvs); - return constr_->containsTuple (tuple); -} - - - -bool -Parfactor::containsGroup (PrvGroup group) const -{ - for (size_t i = 0; i < args_.size(); i++) { - if (args_[i].group() == group) { - return true; - } - } - return false; -} - - - -bool -Parfactor::containsGroups (vector groups) const -{ - for (size_t i = 0; i < groups.size(); i++) { - if (containsGroup (groups[i]) == false) { - return false; - } - } - return true; -} - - - -unsigned -Parfactor::nrFormulas (LogVar X) const -{ - unsigned count = 0; - for (size_t i = 0; i < args_.size(); i++) { - if (args_[i].contains (X)) { - count ++; - } - } - return count; -} - - - -int -Parfactor::indexOfLogVar (LogVar X) const -{ - size_t idx = args_.size(); - assert (nrFormulas (X) == 1); - for (size_t i = 0; i < args_.size(); i++) { - if (args_[i].contains (X)) { - idx = i; - break; - } - } - return idx; -} - - - -int -Parfactor::indexOfGroup (PrvGroup group) const -{ - size_t pos = args_.size(); - for (size_t i = 0; i < args_.size(); i++) { - if (args_[i].group() == group) { - pos = i; - break; - } - } - return pos; -} - - - -unsigned -Parfactor::nrFormulasWithGroup (PrvGroup group) const -{ - unsigned count = 0; - for (size_t i = 0; i < args_.size(); i++) { - if (args_[i].group() == group) { - count ++; - } - } - return count; -} - - - -vector -Parfactor::getAllGroups (void) const -{ - vector groups (args_.size()); - for (size_t i = 0; i < args_.size(); i++) { - groups[i] = args_[i].group(); - } - return groups; -} - - - -string -Parfactor::getLabel (void) const -{ - stringstream ss; - ss << "phi(" ; - for (size_t i = 0; i < args_.size(); i++) { - if (i != 0) ss << "," ; - ss << args_[i]; - } - ss << ")" ; - ConstraintTree copy (*constr_); - copy.moveToTop (copy.logVarSet().elements()); - ss << "|" << copy.tupleSet(); - return ss.str(); -} - - - -void -Parfactor::print (bool printParams) const -{ - cout << "Formulas: " ; - for (size_t i = 0; i < args_.size(); i++) { - if (i != 0) cout << ", " ; - cout << args_[i]; - } - cout << endl; - if (args_[0].group() != Util::maxUnsigned()) { - vector groups; - for (size_t i = 0; i < args_.size(); i++) { - groups.push_back (string ("g") + Util::toString (args_[i].group())); - } - cout << "Groups: " << groups << endl; - } - cout << "LogVars: " << constr_->logVarSet() << endl; - cout << "Ranges: " << ranges_ << endl; - if (printParams == false) { - cout << "Params: " ; - if (params_.size() <= 32) { - cout.precision(10); - cout << params_ << endl; - } else { - cout << "|" << params_.size() << "|" << endl; - } - } - ConstraintTree copy (*constr_); - copy.moveToTop (copy.logVarSet().elements()); - cout << "Tuples: " << copy.tupleSet() << endl; - if (printParams) { - printParameters(); - } -} - - - -void -Parfactor::printParameters (void) const -{ - vector jointStrings; - Indexer indexer (ranges_); - while (indexer.valid()) { - stringstream ss; - for (size_t i = 0; i < args_.size(); i++) { - if (i != 0) ss << ", " ; - if (args_[i].isCounting()) { - unsigned N = constr_->getConditionalCount ( - args_[i].countedLogVar()); - HistogramSet hs (N, args_[i].range()); - unsigned c = 0; - while (c < indexer[i]) { - hs.nextHistogram(); - c ++; - } - ss << hs; - } else { - ss << indexer[i]; - } - } - jointStrings.push_back (ss.str()); - ++ indexer; - } - for (size_t i = 0; i < params_.size(); i++) { - cout << "f(" << jointStrings[i] << ")" ; - cout << " = " << params_[i] << endl; - } -} - - - -void -Parfactor::printProjections (void) const -{ - ConstraintTree copy (*constr_); - - LogVarSet Xs = copy.logVarSet(); - for (size_t i = 0; i < Xs.size(); i++) { - cout << "-> projection of " << Xs[i] << ": " ; - cout << copy.tupleSet ({Xs[i]}) << endl; - } -} - - - -void -Parfactor::expandPotential ( - size_t fIdx, - unsigned newRange, - const vector& sumIndexes) -{ - ullong newSize = (params_.size() / ranges_[fIdx]) * newRange; - if (newSize > params_.max_size()) { - cerr << "Error: an overflow occurred when performing expansion." ; - cerr << endl; - exit (EXIT_FAILURE); - } - - Params backup = params_; - params_.clear(); - params_.reserve (newSize); - - size_t prod = 1; - vector offsets (ranges_.size()); - for (size_t i = ranges_.size(); i-- > 0; ) { - offsets[i] = prod; - prod *= ranges_[i]; - } - - size_t index = 0; - ranges_[fIdx] = newRange; - vector indices (ranges_.size(), 0); - for (size_t k = 0; k < newSize; k++) { - assert (index < backup.size()); - params_.push_back (backup[index]); - for (size_t i = ranges_.size(); i-- > 0; ) { - indices[i] ++; - if (i == fIdx) { - if (indices[i] != ranges_[i]) { - int diff = sumIndexes[indices[i]] - sumIndexes[indices[i] - 1]; - index += diff * offsets[i]; - break; - } else { - // last index contains the old range minus 1 - index -= sumIndexes.back() * offsets[i]; - indices[i] = 0; - } - } else { - if (indices[i] != ranges_[i]) { - index += offsets[i]; - break; - } else { - index -= (ranges_[i] - 1) * offsets[i]; - indices[i] = 0; - } - } - } - } -} - - - -void -Parfactor::simplifyCountingFormulas (size_t fIdx) -{ - // check if we can simplify the parfactor - for (size_t i = 0; i < args_.size(); i++) { - if (i != fIdx && - args_[i].isCounting() && - args_[i].group() == args_[fIdx].group()) { - // if they only differ in the name of the counting log var - if ((args_[i].logVarSet() - args_[i].countedLogVar()) == - (args_[fIdx].logVarSet()) - args_[fIdx].countedLogVar() && - ranges_[i] == ranges_[fIdx]) { - simplifyParfactor (fIdx, i); - break; - } - } - } -} - - - -void -Parfactor::simplifyGrounds (void) -{ - if (args_.size() == 1) { - return; - } - LogVarSet singletons = constr_->singletons(); - for (long i = 0; i < (long)args_.size() - 1; i++) { - for (size_t j = i + 1; j < args_.size(); j++) { - if (args_[i].group() == args_[j].group() && - singletons.contains (args_[i].logVarSet()) && - singletons.contains (args_[j].logVarSet())) { - simplifyParfactor (i, j); - i --; - break; - } - } - } -} - - - -bool -Parfactor::canMultiply (Parfactor* g1, Parfactor* g2) -{ - std::pair res = getAlignLogVars (g1, g2); - LogVarSet Xs_1 (res.first); - LogVarSet Xs_2 (res.second); - LogVarSet Y_1 = g1->logVarSet() - Xs_1; - LogVarSet Y_2 = g2->logVarSet() - Xs_2; - Y_1 -= g1->countedLogVars(); - Y_2 -= g2->countedLogVars(); - return g1->constr()->isCountNormalized (Y_1) && - g2->constr()->isCountNormalized (Y_2); -} - - - -void -Parfactor::simplifyParfactor (size_t fIdx1, size_t fIdx2) -{ - Params backup = params_; - params_.clear(); - Indexer indexer (ranges_); - while (indexer.valid()) { - if (indexer[fIdx1] == indexer[fIdx2]) { - params_.push_back (backup[indexer]); - } - ++ indexer; - } - for (size_t i = 0; i < args_[fIdx2].logVars().size(); i++) { - if (nrFormulas (args_[fIdx2].logVars()[i]) == 1) { - constr_->remove ({ args_[fIdx2].logVars()[i] }); - } - } - args_.erase (args_.begin() + fIdx2); - ranges_.erase (ranges_.begin() + fIdx2); -} - - - -std::pair -Parfactor::getAlignLogVars (Parfactor* g1, Parfactor* g2) -{ - g1->simplifyGrounds(); - g2->simplifyGrounds(); - LogVars Xs_1, Xs_2; - TinySet matchedI; - TinySet matchedJ; - ProbFormulas& formulas1 = g1->arguments(); - ProbFormulas& formulas2 = g2->arguments(); - for (size_t i = 0; i < formulas1.size(); i++) { - for (size_t j = 0; j < formulas2.size(); j++) { - if (formulas1[i].group() == formulas2[j].group() && - g1->range (i) == g2->range (j) && - matchedI.contains (i) == false && - matchedJ.contains (j) == false) { - Util::addToVector (Xs_1, formulas1[i].logVars()); - Util::addToVector (Xs_2, formulas2[j].logVars()); - matchedI.insert (i); - matchedJ.insert (j); - } - } - } - return make_pair (Xs_1, Xs_2); -} - - - -void -Parfactor::alignAndExponentiate (Parfactor* g1, Parfactor* g2) -{ - alignLogicalVars (g1, g2); - LogVarSet comm = g1->logVarSet() & g2->logVarSet(); - LogVarSet Y_1 = g1->logVarSet() - comm; - LogVarSet Y_2 = g2->logVarSet() - comm; - Y_1 -= g1->countedLogVars(); - Y_2 -= g2->countedLogVars(); - assert (g1->constr()->isCountNormalized (Y_1)); - assert (g2->constr()->isCountNormalized (Y_2)); - unsigned condCount1 = g1->constr()->getConditionalCount (Y_1); - unsigned condCount2 = g2->constr()->getConditionalCount (Y_2); - LogAware::pow (g1->params(), 1.0 / condCount2); - LogAware::pow (g2->params(), 1.0 / condCount1); -} - - - -void -Parfactor::alignLogicalVars (Parfactor* g1, Parfactor* g2) -{ - std::pair res = getAlignLogVars (g1, g2); - const LogVars& alignLvs1 = res.first; - const LogVars& alignLvs2 = res.second; - // cout << "ALIGNING :::::::::::::::::" << endl; - // g1->print(); - // cout << "AND" << endl; - // g2->print(); - // cout << "-> align lvs1 = " << alignLvs1 << endl; - // cout << "-> align lvs2 = " << alignLvs2 << endl; - LogVar freeLogVar (0); - Substitution theta1, theta2; - for (size_t i = 0; i < alignLvs1.size(); i++) { - bool b1 = theta1.containsReplacementFor (alignLvs1[i]); - bool b2 = theta2.containsReplacementFor (alignLvs2[i]); - if (b1 == false && b2 == false) { - theta1.add (alignLvs1[i], freeLogVar); - theta2.add (alignLvs2[i], freeLogVar); - ++ freeLogVar; - } else if (b1 == false && b2) { - theta1.add (alignLvs1[i], theta2.newNameFor (alignLvs2[i])); - } else if (b1 && b2 == false) { - theta2.add (alignLvs2[i], theta1.newNameFor (alignLvs1[i])); - } - } - - const LogVarSet& allLvs1 = g1->logVarSet(); - for (size_t i = 0; i < allLvs1.size(); i++) { - if (theta1.containsReplacementFor (allLvs1[i]) == false) { - theta1.add (allLvs1[i], freeLogVar); - ++ freeLogVar; - } - } - const LogVarSet& allLvs2 = g2->logVarSet(); - for (size_t i = 0; i < allLvs2.size(); i++) { - if (theta2.containsReplacementFor (allLvs2[i]) == false) { - theta2.add (allLvs2[i], freeLogVar); - ++ freeLogVar; - } - } - - // handle this type of situation: - // g1 = p(X), q(X) ; X in {(p1),(p2)} - // g2 = p(X), q(Y) ; (X,Y) in {(p1,p2),(p2,p1)} - LogVars discardedLvs1 = theta1.getDiscardedLogVars(); - for (size_t i = 0; i < discardedLvs1.size(); i++) { - if (g1->constr()->isSingleton (discardedLvs1[i]) && - g1->nrFormulas (discardedLvs1[i]) == 1) { - g1->constr()->remove (discardedLvs1[i]); - } else { - LogVar X_new = ++ g1->constr()->logVarSet().back(); - theta1.rename (discardedLvs1[i], X_new); - } - } - LogVars discardedLvs2 = theta2.getDiscardedLogVars(); - for (size_t i = 0; i < discardedLvs2.size(); i++) { - if (g2->constr()->isSingleton (discardedLvs2[i]) && - g2->nrFormulas (discardedLvs2[i]) == 1) { - g2->constr()->remove (discardedLvs2[i]); - } else { - LogVar X_new = ++ g2->constr()->logVarSet().back(); - theta2.rename (discardedLvs2[i], X_new); - } - } - - // cout << "theta1: " << theta1 << endl; - // cout << "theta2: " << theta2 << endl; - g1->applySubstitution (theta1); - g2->applySubstitution (theta2); -} - diff --git a/packages/CLPBN/horus2/Parfactor.h b/packages/CLPBN/horus2/Parfactor.h deleted file mode 100644 index 1c65c2ea0..000000000 --- a/packages/CLPBN/horus2/Parfactor.h +++ /dev/null @@ -1,125 +0,0 @@ -#ifndef HORUS_PARFACTOR_H -#define HORUS_PARFACTOR_H - -#include -#include - -#include "ProbFormula.h" -#include "ConstraintTree.h" -#include "LiftedUtils.h" -#include "Horus.h" - -#include "Factor.h" - -class Parfactor : public TFactor -{ - public: - Parfactor ( - const ProbFormulas&, - const Params&, - const Tuples&, - unsigned distId); - - Parfactor (const Parfactor*, const Tuple&); - - Parfactor (const Parfactor*, ConstraintTree*); - - Parfactor (const Parfactor&); - - ~Parfactor (void); - - ConstraintTree* constr (void) { return constr_; } - - const ConstraintTree* constr (void) const { return constr_; } - - const LogVars& logVars (void) const { return constr_->logVars(); } - - const LogVarSet& logVarSet (void) const { return constr_->logVarSet(); } - - LogVarSet countedLogVars (void) const; - - LogVarSet uncountedLogVars (void) const; - - LogVarSet elimLogVars (void) const; - - LogVarSet exclusiveLogVars (size_t fIdx) const; - - void sumOutIndex (size_t fIdx); - - void multiply (Parfactor&); - - bool canCountConvert (LogVar X); - - void countConvert (LogVar); - - void expand (LogVar, LogVar, LogVar); - - void fullExpand (LogVar); - - void reorderAccordingGrounds (const Grounds&); - - void absorveEvidence (const ProbFormula&, unsigned); - - void setNewGroups (void); - - void applySubstitution (const Substitution&); - - size_t indexOfGround (const Ground&) const; - - PrvGroup findGroup (const Ground&) const; - - bool containsGround (const Ground&) const; - - bool containsGrounds (const Grounds&) const; - - bool containsGroup (PrvGroup) const; - - bool containsGroups (vector) const; - - unsigned nrFormulas (LogVar) const; - - int indexOfLogVar (LogVar) const; - - int indexOfGroup (PrvGroup) const; - - unsigned nrFormulasWithGroup (PrvGroup) const; - - vector getAllGroups (void) const; - - void print (bool = false) const; - - void printParameters (void) const; - - void printProjections (void) const; - - string getLabel (void) const; - - void simplifyGrounds (void); - - static bool canMultiply (Parfactor*, Parfactor*); - - private: - - void simplifyCountingFormulas (size_t fIdx); - - void simplifyParfactor (size_t fIdx1, size_t fIdx2); - - static std::pair getAlignLogVars ( - Parfactor* g1, Parfactor* g2); - - void expandPotential (size_t fIdx, unsigned newRange, - const vector& sumIndexes); - - static void alignAndExponentiate (Parfactor*, Parfactor*); - - static void alignLogicalVars (Parfactor*, Parfactor*); - - ConstraintTree* constr_; - -}; - - -typedef vector Parfactors; - -#endif // HORUS_PARFACTOR_H - diff --git a/packages/CLPBN/horus2/ParfactorList.cpp b/packages/CLPBN/horus2/ParfactorList.cpp deleted file mode 100644 index 1de1ccc7d..000000000 --- a/packages/CLPBN/horus2/ParfactorList.cpp +++ /dev/null @@ -1,638 +0,0 @@ -#include - -#include "ParfactorList.h" - - -ParfactorList::ParfactorList (const ParfactorList& pfList) -{ - ParfactorList::const_iterator it = pfList.begin(); - while (it != pfList.end()) { - addShattered (new Parfactor (**it)); - ++ it; - } -} - - - -ParfactorList::ParfactorList (const Parfactors& pfs) -{ - add (pfs); -} - - - -ParfactorList::~ParfactorList (void) -{ - ParfactorList::const_iterator it = pfList_.begin(); - while (it != pfList_.end()) { - delete *it; - ++ it; - } -} - - - -void -ParfactorList::add (Parfactor* pf) -{ - pf->setNewGroups(); - addToShatteredList (pf); -} - - - -void -ParfactorList::add (const Parfactors& pfs) -{ - for (size_t i = 0; i < pfs.size(); i++) { - pfs[i]->setNewGroups(); - addToShatteredList (pfs[i]); - } -} - - - -void -ParfactorList::addShattered (Parfactor* pf) -{ - assert (isAllShattered()); - pfList_.push_back (pf); - assert (isAllShattered()); -} - - - -list::iterator -ParfactorList::insertShattered ( - list::iterator it, - Parfactor* pf) -{ - return pfList_.insert (it, pf); - assert (isAllShattered()); -} - - - -list::iterator -ParfactorList::remove (list::iterator it) -{ - return pfList_.erase (it); -} - - - -list::iterator -ParfactorList::removeAndDelete (list::iterator it) -{ - delete *it; - return pfList_.erase (it); -} - - - -bool -ParfactorList::isAllShattered (void) const -{ - if (pfList_.size() <= 1) { - return true; - } - vector pfs (pfList_.begin(), pfList_.end()); - for (size_t i = 0; i < pfs.size(); i++) { - assert (isShattered (pfs[i])); - } - for (size_t i = 0; i < pfs.size() - 1; i++) { - for (size_t j = i + 1; j < pfs.size(); j++) { - if (isShattered (pfs[i], pfs[j]) == false) { - return false; - } - } - } - return true; -} - - - -void -ParfactorList::print (void) const -{ - Parfactors pfVec (pfList_.begin(), pfList_.end()); - std::sort (pfVec.begin(), pfVec.end(), sortByParams()); - for (size_t i = 0; i < pfVec.size(); i++) { - pfVec[i]->print(); - cout << endl; - } -} - - - -ParfactorList& -ParfactorList::operator= (const ParfactorList& pfList) -{ - if (this != &pfList) { - ParfactorList::const_iterator it0 = pfList_.begin(); - while (it0 != pfList_.end()) { - delete *it0; - ++ it0; - } - pfList_.clear(); - ParfactorList::const_iterator it = pfList.begin(); - while (it != pfList.end()) { - addShattered (new Parfactor (**it)); - ++ it; - } - } - return *this; -} - - - -bool -ParfactorList::isShattered (const Parfactor* g) const -{ - const ProbFormulas& formulas = g->arguments(); - if (formulas.size() < 2) { - return true; - } - ConstraintTree ct (*g->constr()); - for (size_t i = 0; i < formulas.size() - 1; i++) { - for (size_t j = i + 1; j < formulas.size(); j++) { - if (formulas[i].group() == formulas[j].group()) { - if (identical ( - formulas[i], *(g->constr()), - formulas[j], *(g->constr())) == false) { - g->print(); - cout << "-> not identical on positions " ; - cout << i << " and " << j << endl; - return false; - } - } else { - if (disjoint ( - formulas[i], *(g->constr()), - formulas[j], *(g->constr())) == false) { - g->print(); - cout << "-> not disjoint on positions " ; - cout << i << " and " << j << endl; - return false; - } - } - } - } - return true; -} - - - -bool -ParfactorList::isShattered ( - const Parfactor* g1, - const Parfactor* g2) const -{ - assert (g1 != g2); - const ProbFormulas& fms1 = g1->arguments(); - const ProbFormulas& fms2 = g2->arguments(); - - for (size_t i = 0; i < fms1.size(); i++) { - for (size_t j = 0; j < fms2.size(); j++) { - if (fms1[i].group() == fms2[j].group()) { - if (identical ( - fms1[i], *(g1->constr()), - fms2[j], *(g2->constr())) == false) { - g1->print(); - cout << "^" << endl; - g2->print(); - cout << "-> not identical on group " << fms1[i].group() << endl; - return false; - } - } else { - if (disjoint ( - fms1[i], *(g1->constr()), - fms2[j], *(g2->constr())) == false) { - g1->print(); - cout << "^" << endl; - g2->print(); - cout << "-> not disjoint on groups " << fms1[i].group(); - cout << " and " << fms2[j].group() << endl; - return false; - } - } - } - } - return true; -} - - - -void -ParfactorList::addToShatteredList (Parfactor* g) -{ - queue residuals; - residuals.push (g); - while (residuals.empty() == false) { - Parfactor* pf = residuals.front(); - bool pfSplitted = false; - list::iterator pfIter; - pfIter = pfList_.begin(); - while (pfIter != pfList_.end()) { - std::pair shattRes; - shattRes = shatter (*pfIter, pf); - if (shattRes.first.empty() == false) { - pfIter = removeAndDelete (pfIter); - Util::addToQueue (residuals, shattRes.first); - } else { - ++ pfIter; - } - if (shattRes.second.empty() == false) { - delete pf; - Util::addToQueue (residuals, shattRes.second); - pfSplitted = true; - break; - } - } - residuals.pop(); - if (pfSplitted == false) { - Parfactors res = shatterAgainstMySelf (pf); - if (res.empty()) { - addShattered (pf); - } else { - Util::addToQueue (residuals, res); - } - } - } - assert (isAllShattered()); -} - - - -Parfactors -ParfactorList::shatterAgainstMySelf (Parfactor* g) -{ - Parfactors pfs; - queue residuals; - residuals.push (g); - bool shattered = true; - while (residuals.empty() == false) { - Parfactor* pf = residuals.front(); - Parfactors res = shatterAgainstMySelf2 (pf); - if (res.empty()) { - assert (isShattered (pf)); - if (shattered) { - return { }; - } - pfs.push_back (pf); - } else { - shattered = false; - for (size_t i = 0; i < res.size(); i++) { - assert (res[i]->constr()->empty() == false); - residuals.push (res[i]); - } - delete pf; - } - residuals.pop(); - } - return pfs; -} - - - -Parfactors -ParfactorList::shatterAgainstMySelf2 (Parfactor* g) -{ - // slip a parfactor with overlapping formulas: - // e.g. {s(X),s(Y)}, with (X,Y) in {(p1,p2),(p1,p3),(p4,p1)} - const ProbFormulas& formulas = g->arguments(); - for (size_t i = 0; i < formulas.size() - 1; i++) { - for (size_t j = i + 1; j < formulas.size(); j++) { - if (formulas[i].sameSkeletonAs (formulas[j])) { - Parfactors res = shatterAgainstMySelf (g, i, j); - if (res.empty() == false) { - return res; - } - } - } - } - return Parfactors(); -} - - - -Parfactors -ParfactorList::shatterAgainstMySelf ( - Parfactor* g, - size_t fIdx1, - size_t fIdx2) -{ - /* - Util::printDashedLine(); - cout << "-> SHATTERING" << endl; - g->print(); - cout << "-> ON: " << g->argument (fIdx1) << "|" ; - cout << g->constr()->tupleSet (g->argument (fIdx1).logVars()) << endl; - cout << "-> ON: " << g->argument (fIdx2) << "|" ; - cout << g->constr()->tupleSet (g->argument (fIdx2).logVars()) << endl; - Util::printDashedLine(); - */ - ProbFormula& f1 = g->argument (fIdx1); - ProbFormula& f2 = g->argument (fIdx2); - if (f1.isAtom()) { - cerr << "Error: a ground occurs twice in the same parfactor." << endl; - cerr << endl; - exit (EXIT_FAILURE); - } - assert (g->constr()->empty() == false); - ConstraintTree ctCopy (*g->constr()); - if (f1.group() == f2.group()) { - assert (identical (f1, *(g->constr()), f2, ctCopy)); - return { }; - } - - g->constr()->moveToTop (f1.logVars()); - ctCopy.moveToTop (f2.logVars()); - - std::pair split1 = - g->constr()->split (f1.logVars(), &ctCopy, f2.logVars()); - ConstraintTree* commCt1 = split1.first; - ConstraintTree* exclCt1 = split1.second; - - if (commCt1->empty()) { - // disjoint - delete commCt1; - delete exclCt1; - return { }; - } - - PrvGroup newGroup = ProbFormula::getNewGroup(); - Parfactors res1 = shatter (g, fIdx1, commCt1, exclCt1, newGroup); - if (res1.empty()) { - res1.push_back (g); - } - - Parfactors res; - ctCopy.moveToTop (f1.logVars()); - for (size_t i = 0; i < res1.size(); i++) { - res1[i]->constr()->moveToTop (f2.logVars()); - std::pair split2; - split2 = res1[i]->constr()->split (f2.logVars(), &ctCopy, f1.logVars()); - ConstraintTree* commCt2 = split2.first; - ConstraintTree* exclCt2 = split2.second; - if (commCt2->empty()) { - if (res1[i] != g) { - res.push_back (res1[i]); - } - delete commCt2; - delete exclCt2; - continue; - } - newGroup = ProbFormula::getNewGroup(); - Parfactors res2 = shatter (res1[i], fIdx2, commCt2, exclCt2, newGroup); - if (res2.empty()) { - if (res1[i] != g) { - res.push_back (res1[i]); - } - } else { - Util::addToVector (res, res2); - for (size_t j = 0; j < res2.size(); j++) { - } - if (res1[i] != g) { - delete res1[i]; - } - } - } - - if (res.empty()) { - g->argument (fIdx2).setGroup (g->argument (fIdx1).group()); - updateGroups (f2.group(), f1.group()); - } - return res; -} - - - -std::pair -ParfactorList::shatter (Parfactor* g1, Parfactor* g2) -{ - ProbFormulas& formulas1 = g1->arguments(); - ProbFormulas& formulas2 = g2->arguments(); - assert (g1 != 0 && g2 != 0 && g1 != g2); - for (size_t i = 0; i < formulas1.size(); i++) { - for (size_t j = 0; j < formulas2.size(); j++) { - if (formulas1[i].sameSkeletonAs (formulas2[j])) { - std::pair res; - res = shatter (i, g1, j, g2); - if (res.first.empty() == false || - res.second.empty() == false) { - return res; - } - } - } - } - return make_pair (Parfactors(), Parfactors()); -} - - - -std::pair -ParfactorList::shatter ( - size_t fIdx1, Parfactor* g1, - size_t fIdx2, Parfactor* g2) -{ - ProbFormula& f1 = g1->argument (fIdx1); - ProbFormula& f2 = g2->argument (fIdx2); - /* - Util::printDashedLine(); - cout << "-> SHATTERING" << endl; - g1->print(); - cout << "-> WITH" << endl; - g2->print(); - cout << "-> ON: " << f1 << "|" ; - cout << g1->constr()->tupleSet (f1.logVars()) << endl; - cout << "-> ON: " << f2 << "|" ; - cout << g2->constr()->tupleSet (f2.logVars()) << endl; - Util::printDashedLine(); - */ - if (f1.isAtom()) { - f2.setGroup (f1.group()); - updateGroups (f2.group(), f1.group()); - return { }; - } - assert (g1->constr()->empty() == false); - assert (g2->constr()->empty() == false); - if (f1.group() == f2.group()) { - assert (identical (f1, *(g1->constr()), f2, *(g2->constr()))); - return { }; - } - - g1->constr()->moveToTop (f1.logVars()); - g2->constr()->moveToTop (f2.logVars()); - - std::pair split1 = - g1->constr()->split (f1.logVars(), g2->constr(), f2.logVars()); - ConstraintTree* commCt1 = split1.first; - ConstraintTree* exclCt1 = split1.second; - - if (commCt1->empty()) { - // disjoint - delete commCt1; - delete exclCt1; - return { }; - } - - std::pair split2 = - g2->constr()->split (f2.logVars(), g1->constr(), f1.logVars()); - ConstraintTree* commCt2 = split2.first; - ConstraintTree* exclCt2 = split2.second; - - assert (commCt1->tupleSet (f1.logVars()) == - commCt2->tupleSet (f2.logVars())); - - // stringstream ss1; ss1 << "" << count << "_A.dot" ; - // stringstream ss2; ss2 << "" << count << "_B.dot" ; - // stringstream ss3; ss3 << "" << count << "_A_comm.dot" ; - // stringstream ss4; ss4 << "" << count << "_A_excl.dot" ; - // stringstream ss5; ss5 << "" << count << "_B_comm.dot" ; - // stringstream ss6; ss6 << "" << count << "_B_excl.dot" ; - // g1->constr()->exportToGraphViz (ss1.str().c_str(), true); - // g2->constr()->exportToGraphViz (ss2.str().c_str(), true); - // commCt1->exportToGraphViz (ss3.str().c_str(), true); - // exclCt1->exportToGraphViz (ss4.str().c_str(), true); - // commCt2->exportToGraphViz (ss5.str().c_str(), true); - // exclCt2->exportToGraphViz (ss6.str().c_str(), true); - - if (exclCt1->empty() && exclCt2->empty()) { - // identical - f2.setGroup (f1.group()); - updateGroups (f2.group(), f1.group()); - delete commCt1; - delete exclCt1; - delete commCt2; - delete exclCt2; - return { }; - } - - PrvGroup group; - if (exclCt1->empty()) { - group = f1.group(); - } else if (exclCt2->empty()) { - group = f2.group(); - } else { - group = ProbFormula::getNewGroup(); - } - Parfactors res1 = shatter (g1, fIdx1, commCt1, exclCt1, group); - Parfactors res2 = shatter (g2, fIdx2, commCt2, exclCt2, group); - return make_pair (res1, res2); -} - - - -Parfactors -ParfactorList::shatter ( - Parfactor* g, - size_t fIdx, - ConstraintTree* commCt, - ConstraintTree* exclCt, - PrvGroup commGroup) -{ - ProbFormula& f = g->argument (fIdx); - if (exclCt->empty()) { - delete commCt; - delete exclCt; - f.setGroup (commGroup); - return { }; - } - - Parfactors result; - if (f.isCounting()) { - LogVar X_new1 = g->constr()->logVarSet().back() + 1; - LogVar X_new2 = g->constr()->logVarSet().back() + 2; - ConstraintTrees cts = g->constr()->jointCountNormalize ( - commCt, exclCt, f.countedLogVar(), X_new1, X_new2); - for (size_t i = 0; i < cts.size(); i++) { - Parfactor* newPf = new Parfactor (g, cts[i]); - if (cts[i]->nrLogVars() == g->constr()->nrLogVars() + 1) { - newPf->expand (f.countedLogVar(), X_new1, X_new2); - assert (g->constr()->getConditionalCount (f.countedLogVar()) == - cts[i]->getConditionalCount (X_new1) + - cts[i]->getConditionalCount (X_new2)); - } else { - assert (g->constr()->getConditionalCount (f.countedLogVar()) == - cts[i]->getConditionalCount (f.countedLogVar())); - } - newPf->setNewGroups(); - result.push_back (newPf); - } - delete commCt; - delete exclCt; - } else { - Parfactor* newPf = new Parfactor (g, commCt); - newPf->setNewGroups(); - newPf->argument (fIdx).setGroup (commGroup); - result.push_back (newPf); - newPf = new Parfactor (g, exclCt); - newPf->setNewGroups(); - result.push_back (newPf); - } - return result; -} - - - -void -ParfactorList::updateGroups (PrvGroup oldGroup, PrvGroup newGroup) -{ - for (ParfactorList::iterator it = pfList_.begin(); - it != pfList_.end(); ++it) { - ProbFormulas& formulas = (*it)->arguments(); - for (size_t i = 0; i < formulas.size(); i++) { - if (formulas[i].group() == oldGroup) { - formulas[i].setGroup (newGroup); - } - } - } -} - - - -bool -ParfactorList::proper ( - const ProbFormula& f1, ConstraintTree ct1, - const ProbFormula& f2, ConstraintTree ct2) const -{ - return disjoint (f1, ct1, f2, ct2) - || identical (f1, ct1, f2, ct2); -} - - - -bool -ParfactorList::identical ( - const ProbFormula& f1, ConstraintTree ct1, - const ProbFormula& f2, ConstraintTree ct2) const -{ - if (f1.sameSkeletonAs (f2) == false) { - return false; - } - if (f1.isAtom()) { - return true; - } - TupleSet ts1 = ct1.tupleSet (f1.logVars()); - TupleSet ts2 = ct2.tupleSet (f2.logVars()); - return ts1 == ts2; -} - - - -bool -ParfactorList::disjoint ( - const ProbFormula& f1, ConstraintTree ct1, - const ProbFormula& f2, ConstraintTree ct2) const -{ - if (f1.sameSkeletonAs (f2) == false) { - return true; - } - if (f1.isAtom()) { - return false; - } - TupleSet ts1 = ct1.tupleSet (f1.logVars()); - TupleSet ts2 = ct2.tupleSet (f2.logVars()); - return (ts1 & ts2).empty(); -} - diff --git a/packages/CLPBN/horus2/ParfactorList.h b/packages/CLPBN/horus2/ParfactorList.h deleted file mode 100644 index 1c6404dcb..000000000 --- a/packages/CLPBN/horus2/ParfactorList.h +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef HORUS_PARFACTORLIST_H -#define HORUS_PARFACTORLIST_H - -#include -#include - -#include "Parfactor.h" -#include "ProbFormula.h" - - -using namespace std; - - -class ParfactorList -{ - public: - ParfactorList (void) { } - - ParfactorList (const ParfactorList&); - - ParfactorList (const Parfactors&); - - ~ParfactorList (void); - - const list& parfactors (void) const { return pfList_; } - - void clear (void) { pfList_.clear(); } - - size_t size (void) const { return pfList_.size(); } - - typedef std::list::iterator iterator; - - iterator begin (void) { return pfList_.begin(); } - - iterator end (void) { return pfList_.end(); } - - typedef std::list::const_iterator const_iterator; - - const_iterator begin (void) const { return pfList_.begin(); } - - const_iterator end (void) const { return pfList_.end(); } - - void add (Parfactor* pf); - - void add (const Parfactors& pfs); - - void addShattered (Parfactor* pf); - - list::iterator insertShattered ( - list::iterator, Parfactor*); - - list::iterator remove (list::iterator); - - list::iterator removeAndDelete (list::iterator); - - bool isAllShattered (void) const; - - void print (void) const; - - ParfactorList& operator= (const ParfactorList& pfList); - - private: - bool isShattered (const Parfactor*) const; - - bool isShattered (const Parfactor*, const Parfactor*) const; - - void addToShatteredList (Parfactor*); - - Parfactors shatterAgainstMySelf (Parfactor* g); - - Parfactors shatterAgainstMySelf2 (Parfactor* g); - - Parfactors shatterAgainstMySelf ( - Parfactor* g, size_t fIdx1, size_t fIdx2); - - std::pair shatter ( - Parfactor*, Parfactor*); - - std::pair shatter ( - size_t, Parfactor*, size_t, Parfactor*); - - Parfactors shatter ( - Parfactor*, - size_t, - ConstraintTree*, - ConstraintTree*, - PrvGroup); - - void updateGroups (PrvGroup group1, PrvGroup group2); - - bool proper ( - const ProbFormula&, ConstraintTree, - const ProbFormula&, ConstraintTree) const; - - bool identical ( - const ProbFormula&, ConstraintTree, - const ProbFormula&, ConstraintTree) const; - - bool disjoint ( - const ProbFormula&, ConstraintTree, - const ProbFormula&, ConstraintTree) const; - - struct sortByParams - { - inline bool operator() (const Parfactor* pf1, const Parfactor* pf2) - { - if (pf1->params().size() < pf2->params().size()) { - return true; - } else if (pf1->params().size() == pf2->params().size() && - pf1->params() < pf2->params()) { - return true; - } - return false; - } - }; - - list pfList_; -}; - -#endif // HORUS_PARFACTORLIST_H - diff --git a/packages/CLPBN/horus2/ProbFormula.cpp b/packages/CLPBN/horus2/ProbFormula.cpp deleted file mode 100644 index fa2d26d05..000000000 --- a/packages/CLPBN/horus2/ProbFormula.cpp +++ /dev/null @@ -1,140 +0,0 @@ -#include "ProbFormula.h" - - -PrvGroup ProbFormula::freeGroup_ = 0; - - - -bool -ProbFormula::sameSkeletonAs (const ProbFormula& f) const -{ - return functor_ == f.functor() && logVars_.size() == f.arity(); -} - - - -bool -ProbFormula::contains (LogVar lv) const -{ - return Util::contains (logVars_, lv); -} - - - -bool -ProbFormula::contains (LogVarSet s) const -{ - return LogVarSet (logVars_).contains (s); -} - - - -size_t -ProbFormula::indexOf (LogVar X) const -{ - return Util::indexOf (logVars_, X); -} - - - -bool -ProbFormula::isAtom (void) const -{ - return logVars_.size() == 0; -} - - - -bool -ProbFormula::isCounting (void) const -{ - return countedLogVar_.valid(); -} - - - -LogVar -ProbFormula::countedLogVar (void) const -{ - assert (isCounting()); - return countedLogVar_; -} - - - -void -ProbFormula::setCountedLogVar (LogVar lv) -{ - countedLogVar_ = lv; -} - - - -void -ProbFormula::clearCountedLogVar (void) -{ - countedLogVar_ = LogVar(); -} - - - -void -ProbFormula::rename (LogVar oldName, LogVar newName) -{ - for (size_t i = 0; i < logVars_.size(); i++) { - if (logVars_[i] == oldName) { - logVars_[i] = newName; - } - } - if (isCounting() && countedLogVar_ == oldName) { - countedLogVar_ = newName; - } -} - - -bool operator== (const ProbFormula& f1, const ProbFormula& f2) -{ - return f1.group_ == f2.group_ && - f1.logVars_ == f2.logVars_; -} - - - -std::ostream& operator<< (ostream &os, const ProbFormula& f) -{ - os << f.functor_; - if (f.isAtom() == false) { - os << "(" ; - for (size_t i = 0; i < f.logVars_.size(); i++) { - if (i != 0) os << ","; - if (f.isCounting() && f.logVars_[i] == f.countedLogVar_) { - os << "#" ; - } - os << f.logVars_[i]; - } - os << ")" ; - } - os << "::" << f.range_; - return os; -} - - - -PrvGroup -ProbFormula::getNewGroup (void) -{ - freeGroup_ ++; - assert (freeGroup_ != numeric_limits::max()); - return freeGroup_; -} - - - -ostream& operator<< (ostream &os, const ObservedFormula& of) -{ - os << of.functor_ << "/" << of.arity_; - os << "|" << of.constr_.tupleSet(); - os << " [evidence=" << of.evidence_ << "]"; - return os; -} - diff --git a/packages/CLPBN/horus2/ProbFormula.h b/packages/CLPBN/horus2/ProbFormula.h deleted file mode 100644 index 63086266a..000000000 --- a/packages/CLPBN/horus2/ProbFormula.h +++ /dev/null @@ -1,114 +0,0 @@ -#ifndef HORUS_PROBFORMULA_H -#define HORUS_PROBFORMULA_H - -#include - -#include "ConstraintTree.h" -#include "LiftedUtils.h" -#include "Horus.h" - -typedef unsigned long PrvGroup; - -class ProbFormula -{ - public: - ProbFormula (Symbol f, const LogVars& lvs, unsigned range) - : functor_(f), logVars_(lvs), range_(range), - countedLogVar_(), group_(numeric_limits::max()) { } - - ProbFormula (Symbol f, unsigned r) - : functor_(f), range_(r), group_(numeric_limits::max()) { } - - Symbol functor (void) const { return functor_; } - - unsigned arity (void) const { return logVars_.size(); } - - unsigned range (void) const { return range_; } - - LogVars& logVars (void) { return logVars_; } - - const LogVars& logVars (void) const { return logVars_; } - - LogVarSet logVarSet (void) const { return LogVarSet (logVars_); } - - PrvGroup group (void) const { return group_; } - - void setGroup (PrvGroup g) { group_ = g; } - - bool sameSkeletonAs (const ProbFormula&) const; - - bool contains (LogVar) const; - - bool contains (LogVarSet) const; - - size_t indexOf (LogVar) const; - - bool isAtom (void) const; - - bool isCounting (void) const; - - LogVar countedLogVar (void) const; - - void setCountedLogVar (LogVar); - - void clearCountedLogVar (void); - - void rename (LogVar, LogVar); - - static PrvGroup getNewGroup (void); - - friend std::ostream& operator<< (ostream &os, const ProbFormula& f); - - friend bool operator== (const ProbFormula& f1, const ProbFormula& f2); - - private: - Symbol functor_; - LogVars logVars_; - unsigned range_; - LogVar countedLogVar_; - PrvGroup group_; - static PrvGroup freeGroup_; -}; - -typedef vector ProbFormulas; - - -class ObservedFormula -{ - public: - ObservedFormula (Symbol f, unsigned a, unsigned ev) - : functor_(f), arity_(a), evidence_(ev), constr_(a) { } - - ObservedFormula (Symbol f, unsigned ev, const Tuple& tuple) - : functor_(f), arity_(tuple.size()), evidence_(ev), constr_(arity_) - { - constr_.addTuple (tuple); - } - - Symbol functor (void) const { return functor_; } - - unsigned arity (void) const { return arity_; } - - unsigned evidence (void) const { return evidence_; } - - void setEvidence (unsigned ev) { evidence_ = ev; } - - ConstraintTree& constr (void) { return constr_; } - - bool isAtom (void) const { return arity_ == 0; } - - void addTuple (const Tuple& tuple) { constr_.addTuple (tuple); } - - friend ostream& operator<< (ostream &os, const ObservedFormula& of); - - private: - Symbol functor_; - unsigned arity_; - unsigned evidence_; - ConstraintTree constr_; -}; - -typedef vector ObservedFormulas; - -#endif // HORUS_PROBFORMULA_H - diff --git a/packages/CLPBN/horus2/TinySet.h b/packages/CLPBN/horus2/TinySet.h deleted file mode 100644 index 4b3c4bd83..000000000 --- a/packages/CLPBN/horus2/TinySet.h +++ /dev/null @@ -1,264 +0,0 @@ -#ifndef HORUS_TINYSET_H -#define HORUS_TINYSET_H - -#include -#include - -using namespace std; - - -template > -class TinySet -{ - public: - - typedef typename vector::iterator iterator; - typedef typename vector::const_iterator const_iterator; - - TinySet (const TinySet& s) - : vec_(s.vec_), cmp_(s.cmp_) { } - - TinySet (const Compare& cmp = Compare()) - : vec_(), cmp_(cmp) { } - - TinySet (const T& t, const Compare& cmp = Compare()) - : vec_(1, t), cmp_(cmp) { } - - TinySet (const vector& elements, const Compare& cmp = Compare()) - : vec_(elements), cmp_(cmp) - { - std::sort (begin(), end(), cmp_); - iterator it = unique_cmp (begin(), end()); - vec_.resize (it - begin()); - } - - iterator insert (const T& t) - { - iterator it = std::lower_bound (begin(), end(), t, cmp_); - if (it == end() || cmp_(t, *it)) { - vec_.insert (it, t); - } - return it; - } - - void insert_sorted (const T& t) - { - vec_.push_back (t); - assert (consistent()); - } - - void remove (const T& t) - { - iterator it = std::lower_bound (begin(), end(), t, cmp_); - if (it != end()) { - vec_.erase (it); - } - } - - const_iterator find (const T& t) const - { - const_iterator it = std::lower_bound (begin(), end(), t, cmp_); - return it == end() || cmp_(t, *it) ? end() : it; - } - - iterator find (const T& t) - { - iterator it = std::lower_bound (begin(), end(), t, cmp_); - return it == end() || cmp_(t, *it) ? end() : it; - } - - /* set union */ - TinySet operator| (const TinySet& s) const - { - TinySet res; - std::set_union ( - vec_.begin(), vec_.end(), - s.vec_.begin(), s.vec_.end(), - std::back_inserter (res.vec_), - cmp_); - return res; - } - - /* set intersection */ - TinySet operator& (const TinySet& s) const - { - TinySet res; - std::set_intersection ( - vec_.begin(), vec_.end(), - s.vec_.begin(), s.vec_.end(), - std::back_inserter (res.vec_), - cmp_); - return res; - } - - /* set difference */ - TinySet operator- (const TinySet& s) const - { - TinySet res; - std::set_difference ( - vec_.begin(), vec_.end(), - s.vec_.begin(), s.vec_.end(), - std::back_inserter (res.vec_), - cmp_); - return res; - } - - TinySet& operator|= (const TinySet& s) - { - return *this = (*this | s); - } - - TinySet& operator&= (const TinySet& s) - { - return *this = (*this & s); - } - - TinySet& operator-= (const TinySet& s) - { - return *this = (*this - s); - } - - bool contains (const T& t) const - { - return std::binary_search ( - vec_.begin(), vec_.end(), t, cmp_); - } - - bool contains (const TinySet& s) const - { - return std::includes ( - vec_.begin(), - vec_.end(), - s.vec_.begin(), - s.vec_.end(), - cmp_); - } - - bool in (const TinySet& s) const - { - return std::includes ( - s.vec_.begin(), - s.vec_.end(), - vec_.begin(), - vec_.end(), - cmp_); - } - - bool intersects (const TinySet& s) const - { - return (*this & s).size() > 0; - } - - const T& operator[] (typename vector::size_type i) const - { - return vec_[i]; - } - - T& operator[] (typename vector::size_type i) - { - return vec_[i]; - } - - T front (void) const - { - return vec_.front(); - } - - T& front (void) - { - return vec_.front(); - } - - T back (void) const - { - return vec_.back(); - } - - T& back (void) - { - return vec_.back(); - } - - const vector& elements (void) const - { - return vec_; - } - - bool empty (void) const - { - return size() == 0; - } - - typename vector::size_type size (void) const - { - return vec_.size(); - } - - void clear (void) - { - vec_.clear(); - } - - void reserve (typename vector::size_type size) - { - vec_.reserve (size); - } - - iterator begin (void) { return vec_.begin(); } - iterator end (void) { return vec_.end(); } - const_iterator begin (void) const { return vec_.begin(); } - const_iterator end (void) const { return vec_.end(); } - - friend bool operator== (const TinySet& s1, const TinySet& s2) - { - return s1.vec_ == s2.vec_; - } - - friend bool operator!= (const TinySet& s1, const TinySet& s2) - { - return ! (s1.vec_ == s2.vec_); - } - - friend std::ostream& operator << (std::ostream& out, const TinySet& s) - { - out << "{" ; - typename vector::size_type i; - for (i = 0; i < s.size(); i++) { - out << ((i != 0) ? "," : "") << s.vec_[i]; - } - out << "}" ; - return out; - } - - private: - iterator unique_cmp (iterator first, iterator last) - { - if (first == last) { - return last; - } - iterator result = first; - while (++first != last) { - if (cmp_(*result, *first)) { - *(++result) = *first; - } - } - return ++result; - } - - bool consistent (void) const - { - typename vector::size_type i; - for (i = 0; i < vec_.size() - 1; i++) { - if ( ! cmp_(vec_[i], vec_[i + 1])) { - return false; - } - } - return true; - } - - vector vec_; - Compare cmp_; -}; - -#endif // HORUS_TINYSET_H - diff --git a/packages/CLPBN/horus2/Util.cpp b/packages/CLPBN/horus2/Util.cpp deleted file mode 100644 index 0f3ce6544..000000000 --- a/packages/CLPBN/horus2/Util.cpp +++ /dev/null @@ -1,429 +0,0 @@ -#include - -#include -#include - -#include "Util.h" -#include "Indexer.h" -#include "ElimGraph.h" - - -namespace Globals { -bool logDomain = false; - -unsigned verbosity = 0; - -LiftedSolverType liftedSolver = LiftedSolverType::LVE; - -GroundSolverType groundSolver = GroundSolverType::VE; - -}; - - - -namespace BpOptions { -Schedule schedule = BpOptions::Schedule::SEQ_FIXED; -//Schedule schedule = BpOptions::Schedule::SEQ_RANDOM; -//Schedule schedule = BpOptions::Schedule::PARALLEL; -//Schedule schedule = BpOptions::Schedule::MAX_RESIDUAL; -double accuracy = 0.0001; -unsigned maxIter = 1000; -} - - - -namespace Util { - - -template <> std::string -toString (const bool& b) -{ - std::stringstream ss; - ss << std::boolalpha << b; - return ss.str(); -} - - - -unsigned -stringToUnsigned (string str) -{ - int val; - stringstream ss; - ss << str; - ss >> val; - if (val < 0) { - cerr << "Error: the number readed is negative." << endl; - exit (EXIT_FAILURE); - } - return static_cast (val); -} - - - -double -stringToDouble (string str) -{ - double val; - stringstream ss; - ss << str; - ss >> val; - return val; -} - - - -double -factorial (unsigned num) -{ - double result = 1.0; - for (unsigned i = 1; i <= num; i++) { - result *= i; - } - return result; -} - - - -double -logFactorial (unsigned num) -{ - double result = 0.0; - if (num < 150) { - result = std::log (factorial (num)); - } else { - for (unsigned i = 1; i <= num; i++) { - result += std::log (i); - } - } - return result; -} - - - -unsigned -nrCombinations (unsigned n, unsigned k) -{ - assert (n >= k); - int diff = n - k; - unsigned result = 0; - if (n < 150) { - unsigned prod = 1; - for (int i = n; i > diff; i--) { - prod *= i; - } - result = prod / factorial (k); - } else { - double prod = 0.0; - for (int i = n; i > diff; i--) { - prod += std::log (i); - } - prod -= logFactorial (k); - result = static_cast (std::exp (prod)); - } - return result; -} - - - -size_t -sizeExpected (const Ranges& ranges) -{ - return std::accumulate (ranges.begin(), - ranges.end(), 1, multiplies()); -} - - - -unsigned -nrDigits (int num) -{ - unsigned count = 1; - while (num >= 10) { - num /= 10; - count ++; - } - return count; -} - - - -bool -isInteger (const string& s) -{ - stringstream ss1 (s); - stringstream ss2; - int integer; - ss1 >> integer; - ss2 << integer; - return (ss1.str() == ss2.str()); -} - - - -string -parametersToString (const Params& v, unsigned precision) -{ - stringstream ss; - ss.precision (precision); - ss << "[" ; - for (size_t i = 0; i < v.size(); i++) { - if (i != 0) ss << ", " ; - ss << v[i]; - } - ss << "]" ; - return ss.str(); -} - - - -vector -getStateLines (const Vars& vars) -{ - Ranges ranges; - for (size_t i = 0; i < vars.size(); i++) { - ranges.push_back (vars[i]->range()); - } - Indexer indexer (ranges); - vector jointStrings; - while (indexer.valid()) { - stringstream ss; - for (size_t i = 0; i < vars.size(); i++) { - if (i != 0) ss << ", " ; - ss << vars[i]->label() << "=" ; - ss << vars[i]->states()[(indexer[i])]; - } - jointStrings.push_back (ss.str()); - ++ indexer; - } - return jointStrings; -} - - - -bool -setHorusFlag (string key, string value) -{ - bool returnVal = true; - if (key == "verbosity") { - stringstream ss; - ss << value; - ss >> Globals::verbosity; - } else if (key == "lifted_solver") { - if ( value == "lve") { - Globals::liftedSolver = LiftedSolverType::LVE; - } else if (value == "lbp") { - Globals::liftedSolver = LiftedSolverType::LBP; - } else if (value == "lkc") { - Globals::liftedSolver = LiftedSolverType::LKC; - } else { - cerr << "warning: invalid value `" << value << "' " ; - cerr << "for `" << key << "'" << endl; - returnVal = false; - } - } else if (key == "ground_solver") { - if ( value == "ve") { - Globals::groundSolver = GroundSolverType::VE; - } else if (value == "bp") { - Globals::groundSolver = GroundSolverType::BP; - } else if (value == "cbp") { - Globals::groundSolver = GroundSolverType::CBP; - } else { - cerr << "warning: invalid value `" << value << "' " ; - cerr << "for `" << key << "'" << endl; - returnVal = false; - } - } else if (key == "elim_heuristic") { - if ( value == "sequential") { - ElimGraph::elimHeuristic = ElimHeuristic::SEQUENTIAL; - } else if (value == "min_neighbors") { - ElimGraph::elimHeuristic = ElimHeuristic::MIN_NEIGHBORS; - } else if (value == "min_weight") { - ElimGraph::elimHeuristic = ElimHeuristic::MIN_WEIGHT; - } else if (value == "min_fill") { - ElimGraph::elimHeuristic = ElimHeuristic::MIN_FILL; - } else if (value == "weighted_min_fill") { - ElimGraph::elimHeuristic = ElimHeuristic::WEIGHTED_MIN_FILL; - } else { - cerr << "warning: invalid value `" << value << "' " ; - cerr << "for `" << key << "'" << endl; - returnVal = false; - } - } else if (key == "schedule") { - if ( value == "seq_fixed") { - BpOptions::schedule = BpOptions::Schedule::SEQ_FIXED; - } else if (value == "seq_random") { - BpOptions::schedule = BpOptions::Schedule::SEQ_RANDOM; - } else if (value == "parallel") { - BpOptions::schedule = BpOptions::Schedule::PARALLEL; - } else if (value == "max_residual") { - BpOptions::schedule = BpOptions::Schedule::MAX_RESIDUAL; - } else { - cerr << "warning: invalid value `" << value << "' " ; - cerr << "for `" << key << "'" << endl; - returnVal = false; - } - } else if (key == "accuracy") { - stringstream ss; - ss << value; - ss >> BpOptions::accuracy; - } else if (key == "max_iter") { - stringstream ss; - ss << value; - ss >> BpOptions::maxIter; - } else if (key == "use_logarithms") { - if ( value == "true") { - Globals::logDomain = true; - } else if (value == "false") { - Globals::logDomain = false; - } else { - cerr << "warning: invalid value `" << value << "' " ; - cerr << "for `" << key << "'" << endl; - returnVal = false; - } - } else { - cerr << "warning: invalid key `" << key << "'" << endl; - returnVal = false; - } - return returnVal; -} - - - -void -printHeader (string header, std::ostream& os) -{ - printAsteriskLine (os); - os << header << endl; - printAsteriskLine (os); -} - - - -void -printSubHeader (string header, std::ostream& os) -{ - printDashedLine (os); - os << header << endl; - printDashedLine (os); -} - - - -void -printAsteriskLine (std::ostream& os) -{ - os << "********************************" ; - os << "********************************" ; - os << endl; -} - - - -void -printDashedLine (std::ostream& os) -{ - os << "--------------------------------" ; - os << "--------------------------------" ; - os << endl; -} - - -} - - - -namespace LogAware { - -void -normalize (Params& v) -{ - if (Globals::logDomain) { - double sum = std::accumulate (v.begin(), v.end(), - LogAware::addIdenty(), Util::logSum); - assert (sum != -numeric_limits::infinity()); - v -= sum; - } else { - double sum = std::accumulate (v.begin(), v.end(), 0.0); - assert (sum != 0.0); - v /= sum; - } -} - - - -double -getL1Distance (const Params& v1, const Params& v2) -{ - assert (v1.size() == v2.size()); - double dist = 0.0; - if (Globals::logDomain) { - dist = std::inner_product (v1.begin(), v1.end(), v2.begin(), 0.0, - std::plus(), FuncObject::abs_diff_exp()); - } else { - dist = std::inner_product (v1.begin(), v1.end(), v2.begin(), 0.0, - std::plus(), FuncObject::abs_diff()); - } - return dist; -} - - - -double -getMaxNorm (const Params& v1, const Params& v2) -{ - assert (v1.size() == v2.size()); - double max = 0.0; - if (Globals::logDomain) { - max = std::inner_product (v1.begin(), v1.end(), v2.begin(), 0.0, - FuncObject::max(), FuncObject::abs_diff_exp()); - } else { - max = std::inner_product (v1.begin(), v1.end(), v2.begin(), 0.0, - FuncObject::max(), FuncObject::abs_diff()); - } - return max; -} - - - -double -pow (double base, unsigned iexp) -{ - return Globals::logDomain - ? base * iexp - : std::pow (base, iexp); -} - - - -double -pow (double base, double exp) -{ - // `expoent' should not be in log domain - return Globals::logDomain - ? base * exp - : std::pow (base, exp); -} - - - -void -pow (Params& v, unsigned iexp) -{ - if (iexp == 1) { - return; - } - Globals::logDomain ? v *= iexp : v ^= (int)iexp; -} - - - -void -pow (Params& v, double exp) -{ - // `expoent' should not be in log domain - Globals::logDomain ? v *= exp : v ^= exp; -} - -} - diff --git a/packages/CLPBN/horus2/Util.h b/packages/CLPBN/horus2/Util.h deleted file mode 100644 index 38a088714..000000000 --- a/packages/CLPBN/horus2/Util.h +++ /dev/null @@ -1,422 +0,0 @@ -#ifndef HORUS_UTIL_H -#define HORUS_UTIL_H - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include "Horus.h" - -using namespace std; - - -namespace { -const double NEG_INF = -numeric_limits::infinity(); -}; - - -namespace Util { - -template void addToVector (vector&, const vector&); - -template void addToSet (set&, const vector&); - -template void addToQueue (queue&, const vector&); - -template bool contains (const vector&, const T&); - -template bool contains (const set&, const T&); - -template bool contains ( - const unordered_map&, const K&); - -template size_t indexOf (const vector&, const T&); - -template -void apply_n_times (Params& v1, const Params& v2, unsigned repetitions, Operation); - -template void log (vector&); - -template void exp (vector&); - -template string elementsToString ( - const vector& v, string sep = " "); - -template std::string toString (const T&); - -template <> std::string toString (const bool&); - -double logSum (double, double); - -unsigned maxUnsigned (void); - -unsigned stringToUnsigned (string); - -double stringToDouble (string); - -double factorial (unsigned); - -double logFactorial (unsigned); - -unsigned nrCombinations (unsigned, unsigned); - -size_t sizeExpected (const Ranges&); - -unsigned nrDigits (int); - -bool isInteger (const string&); - -string parametersToString (const Params&, unsigned = Constants::PRECISION); - -vector getStateLines (const Vars&); - -bool setHorusFlag (string key, string value); - -void printHeader (string, std::ostream& os = std::cout); - -void printSubHeader (string, std::ostream& os = std::cout); - -void printAsteriskLine (std::ostream& os = std::cout); - -void printDashedLine (std::ostream& os = std::cout); - -}; - - - -template void -Util::addToVector (vector& v, const vector& elements) -{ - v.insert (v.end(), elements.begin(), elements.end()); -} - - - -template void -Util::addToSet (set& s, const vector& elements) -{ - s.insert (elements.begin(), elements.end()); -} - - - -template void -Util::addToQueue (queue& q, const vector& elements) -{ - for (size_t i = 0; i < elements.size(); i++) { - q.push (elements[i]); - } -} - - - -template bool -Util::contains (const vector& v, const T& e) -{ - return std::find (v.begin(), v.end(), e) != v.end(); -} - - - -template bool -Util::contains (const set& s, const T& e) -{ - return s.find (e) != s.end(); -} - - - -template bool -Util::contains (const unordered_map& m, const K& k) -{ - return m.find (k) != m.end(); -} - - - -template size_t -Util::indexOf (const vector& v, const T& e) -{ - return std::distance (v.begin(), - std::find (v.begin(), v.end(), e)); -} - - - -template void -Util::apply_n_times (Params& v1, const Params& v2, unsigned repetitions, - Operation unary_op) -{ - Params::iterator first = v1.begin(); - Params::const_iterator last = v1.end(); - Params::const_iterator first2 = v2.begin(); - Params::const_iterator last2 = v2.end(); - while (first != last) { - for (first2 = v2.begin(); first2 != last2; ++first2) { - std::transform (first, first + repetitions, first, - std::bind1st (unary_op, *first2)); - first += repetitions; - } - } -} - - - -template void -Util::log (vector& v) -{ - std::transform (v.begin(), v.end(), v.begin(), ::log); -} - - - -template void -Util::exp (vector& v) -{ - std::transform (v.begin(), v.end(), v.begin(), ::exp); -} - - - -template string -Util::elementsToString (const vector& v, string sep) -{ - stringstream ss; - for (size_t i = 0; i < v.size(); i++) { - ss << ((i != 0) ? sep : "") << v[i]; - } - return ss.str(); -} - - - -template std::string -Util::toString (const T& t) -{ - std::stringstream ss; - ss << t; - return ss.str(); -} - - - -inline double -Util::logSum (double x, double y) -{ - // std::log (std::exp (x) + std::exp (y)) can overflow! - assert (std::isnan (x) == false); - assert (std::isnan (y) == false); - if (x == NEG_INF) { - return y; - } - if (y == NEG_INF) { - return x; - } - // if one value is much smaller than the other, - // keep the larger value - const double tol = 460.517; // log (1e200) - if (x < y - tol) { - return y; - } - if (y < x - tol) { - return x; - } - assert (std::isnan (x - y) == false); - const double exp_diff = std::exp (x - y); - if (std::isfinite (exp_diff) == false) { - // difference is too large - return x > y ? x : y; - } - // otherwise return the sum - return y + std::log (static_cast(1.0) + exp_diff); -} - - - -inline unsigned -Util::maxUnsigned (void) -{ - return numeric_limits::max(); -} - - - -namespace LogAware { - -inline double one() { return Globals::logDomain ? 0.0 : 1.0; } -inline double zero() { return Globals::logDomain ? NEG_INF : 0.0; } -inline double addIdenty() { return Globals::logDomain ? NEG_INF : 0.0; } -inline double multIdenty() { return Globals::logDomain ? 0.0 : 1.0; } -inline double withEvidence() { return Globals::logDomain ? 0.0 : 1.0; } -inline double noEvidence() { return Globals::logDomain ? NEG_INF : 0.0; } -inline double log (double v) { return Globals::logDomain ? ::log (v) : v; } -inline double exp (double v) { return Globals::logDomain ? ::exp (v) : v; } - -void normalize (Params&); - -double getL1Distance (const Params&, const Params&); - -double getMaxNorm (const Params&, const Params&); - -double pow (double, unsigned); - -double pow (double, double); - -void pow (Params&, unsigned); - -void pow (Params&, double); - -}; - - - -template -void operator+=(std::vector& v, double val) -{ - std::transform (v.begin(), v.end(), v.begin(), - std::bind2nd (plus(), val)); -} - - - -template -void operator-=(std::vector& v, double val) -{ - std::transform (v.begin(), v.end(), v.begin(), - std::bind2nd (minus(), val)); -} - - - -template -void operator*=(std::vector& v, double val) -{ - std::transform (v.begin(), v.end(), v.begin(), - std::bind2nd (multiplies(), val)); -} - - - -template -void operator/=(std::vector& v, double val) -{ - std::transform (v.begin(), v.end(), v.begin(), - std::bind2nd (divides(), val)); -} - - - -template -void operator+=(std::vector& a, const std::vector& b) -{ - assert (a.size() == b.size()); - std::transform (a.begin(), a.end(), b.begin(), a.begin(), - plus()); -} - - - -template -void operator-=(std::vector& a, const std::vector& b) -{ - assert (a.size() == b.size()); - std::transform (a.begin(), a.end(), b.begin(), a.begin(), - minus()); -} - - - -template -void operator*=(std::vector& a, const std::vector& b) -{ - assert (a.size() == b.size()); - std::transform (a.begin(), a.end(), b.begin(), a.begin(), - multiplies()); -} - - - -template -void operator/=(std::vector& a, const std::vector& b) -{ - assert (a.size() == b.size()); - std::transform (a.begin(), a.end(), b.begin(), a.begin(), - divides()); -} - - - -template -void operator^=(std::vector& v, double exp) -{ - std::transform (v.begin(), v.end(), v.begin(), - std::bind2nd (ptr_fun (std::pow), exp)); -} - - - -template -void operator^=(std::vector& v, int iexp) -{ - std::transform (v.begin(), v.end(), v.begin(), - std::bind2nd (ptr_fun (std::pow), iexp)); -} - - - -template -std::ostream& operator << (std::ostream& os, const vector& v) -{ - os << "[" ; - os << Util::elementsToString (v, ", "); - os << "]" ; - return os; -} - - -namespace FuncObject { - -template -struct max : public std::binary_function -{ - T operator() (const T& x, const T& y) const - { - return x < y ? y : x; - } -}; - - - -template -struct abs_diff : public std::binary_function -{ - T operator() (const T& x, const T& y) const - { - return std::abs (x - y); - } -}; - - - -template -struct abs_diff_exp : public std::binary_function -{ - T operator() (const T& x, const T& y) const - { - return std::abs (std::exp (x) - std::exp (y)); - } -}; - -} - -#endif // HORUS_UTIL_H - diff --git a/packages/CLPBN/horus2/Var.cpp b/packages/CLPBN/horus2/Var.cpp deleted file mode 100644 index 44ab6b1e4..000000000 --- a/packages/CLPBN/horus2/Var.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include -#include - -#include "Var.h" - -using namespace std; - - -unordered_map Var::varsInfo_; - - -Var::Var (const Var* v) -{ - varId_ = v->varId(); - range_ = v->range(); - evidence_ = v->getEvidence(); - index_ = std::numeric_limits::max(); -} - - - -Var::Var (VarId varId, unsigned range, int evidence) -{ - assert (range != 0); - assert (evidence < (int) range); - varId_ = varId; - range_ = range; - evidence_ = evidence; - index_ = std::numeric_limits::max(); -} - - - -bool -Var::isValidState (int stateIndex) -{ - return stateIndex >= 0 && stateIndex < (int) range_; -} - - - -bool -Var::isValidState (const string& stateName) -{ - States states = Var::getVarInfo (varId_).states; - return Util::contains (states, stateName); -} - - - -void -Var::setEvidence (int ev) -{ - assert (ev < (int) range_); - evidence_ = ev; -} - - - -void -Var::setEvidence (const string& ev) -{ - States states = Var::getVarInfo (varId_).states; - for (size_t i = 0; i < states.size(); i++) { - if (states[i] == ev) { - evidence_ = i; - return; - } - } - assert (false); -} - - - -string -Var::label (void) const -{ - if (Var::varsHaveInfo()) { - return Var::getVarInfo (varId_).label; - } - stringstream ss; - ss << "x" << varId_; - return ss.str(); -} - - - -States -Var::states (void) const -{ - if (Var::varsHaveInfo()) { - return Var::getVarInfo (varId_).states; - } - States states; - for (unsigned i = 0; i < range_; i++) { - stringstream ss; - ss << i ; - states.push_back (ss.str()); - } - return states; -} - diff --git a/packages/CLPBN/horus2/Var.h b/packages/CLPBN/horus2/Var.h deleted file mode 100644 index 8ab580c3a..000000000 --- a/packages/CLPBN/horus2/Var.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef HORUS_VAR_H -#define HORUS_VAR_H - -#include - -#include - -#include "Util.h" -#include "Horus.h" - - -using namespace std; - - -struct VarInfo -{ - VarInfo (string l, const States& sts) : label(l), states(sts) { } - string label; - States states; -}; - - - -class Var -{ - public: - Var (const Var*); - - Var (VarId, unsigned, int = Constants::NO_EVIDENCE); - - virtual ~Var (void) { }; - - VarId varId (void) const { return varId_; } - - unsigned range (void) const { return range_; } - - int getEvidence (void) const { return evidence_; } - - size_t getIndex (void) const { return index_; } - - void setIndex (size_t idx) { index_ = idx; } - - bool hasEvidence (void) const - { - return evidence_ != Constants::NO_EVIDENCE; - } - - operator size_t (void) const { return index_; } - - bool operator== (const Var& var) const - { - assert (!(varId_ == var.varId() && range_ != var.range())); - return varId_ == var.varId(); - } - - bool operator!= (const Var& var) const - { - assert (!(varId_ == var.varId() && range_ != var.range())); - return varId_ != var.varId(); - } - - bool isValidState (int); - - bool isValidState (const string&); - - void setEvidence (int); - - void setEvidence (const string&); - - string label (void) const; - - States states (void) const; - - static void addVarInfo ( - VarId vid, string label, const States& states) - { - assert (Util::contains (varsInfo_, vid) == false); - varsInfo_.insert (make_pair (vid, VarInfo (label, states))); - } - - static VarInfo getVarInfo (VarId vid) - { - assert (Util::contains (varsInfo_, vid)); - return varsInfo_.find (vid)->second; - } - - static bool varsHaveInfo (void) - { - return varsInfo_.size() != 0; - } - - static void clearVarsInfo (void) - { - varsInfo_.clear(); - } - - private: - VarId varId_; - unsigned range_; - int evidence_; - size_t index_; - - static unordered_map varsInfo_; - -}; - -#endif // HORUS_VAR_H - diff --git a/packages/CLPBN/horus2/VarElim.cpp b/packages/CLPBN/horus2/VarElim.cpp deleted file mode 100644 index fb4eecf50..000000000 --- a/packages/CLPBN/horus2/VarElim.cpp +++ /dev/null @@ -1,217 +0,0 @@ -#include - -#include "VarElim.h" -#include "ElimGraph.h" -#include "Factor.h" -#include "Util.h" - - -VarElim::~VarElim (void) -{ - delete factorList_.back(); -} - - - -Params -VarElim::solveQuery (VarIds queryVids) -{ - if (Globals::verbosity > 1) { - cout << "Solving query on " ; - for (size_t i = 0; i < queryVids.size(); i++) { - if (i != 0) cout << ", " ; - cout << fg.getVarNode (queryVids[i])->label(); - } - cout << endl; - } - factorList_.clear(); - varFactors_.clear(); - elimOrder_.clear(); - createFactorList(); - absorveEvidence(); - findEliminationOrder (queryVids); - processFactorList (queryVids); - Params params = factorList_.back()->params(); - if (Globals::logDomain) { - Util::exp (params); - } - return params; -} - - - -void -VarElim::printSolverFlags (void) const -{ - stringstream ss; - ss << "variable elimination [" ; - ss << "elim_heuristic=" ; - ElimHeuristic eh = ElimGraph::elimHeuristic; - switch (eh) { - case SEQUENTIAL: ss << "sequential"; break; - case MIN_NEIGHBORS: ss << "min_neighbors"; break; - case MIN_WEIGHT: ss << "min_weight"; break; - case MIN_FILL: ss << "min_fill"; break; - case WEIGHTED_MIN_FILL: ss << "weighted_min_fill"; break; - } - ss << ",log_domain=" << Util::toString (Globals::logDomain); - ss << "]" ; - cout << ss.str() << endl; -} - - - -void -VarElim::createFactorList (void) -{ - const FacNodes& facNodes = fg.facNodes(); - factorList_.reserve (facNodes.size() * 2); - for (size_t i = 0; i < facNodes.size(); i++) { - factorList_.push_back (new Factor (facNodes[i]->factor())); - const VarNodes& neighs = facNodes[i]->neighbors(); - for (size_t j = 0; j < neighs.size(); j++) { - unordered_map>::iterator it - = varFactors_.find (neighs[j]->varId()); - if (it == varFactors_.end()) { - it = varFactors_.insert (make_pair ( - neighs[j]->varId(), vector())).first; - } - it->second.push_back (i); - } - } -} - - - -void -VarElim::absorveEvidence (void) -{ - if (Globals::verbosity > 2) { - Util::printDashedLine(); - cout << "(initial factor list)" << endl; - printActiveFactors(); - } - const VarNodes& varNodes = fg.varNodes(); - for (size_t i = 0; i < varNodes.size(); i++) { - if (varNodes[i]->hasEvidence()) { - if (Globals::verbosity > 1) { - cout << "-> aborving evidence on "; - cout << varNodes[i]->label() << " = " ; - cout << varNodes[i]->getEvidence() << endl; - } - const vector& idxs = - varFactors_.find (varNodes[i]->varId())->second; - for (size_t j = 0; j < idxs.size(); j++) { - Factor* factor = factorList_[idxs[j]]; - if (factor->nrArguments() == 1) { - factorList_[idxs[j]] = 0; - } else { - factorList_[idxs[j]]->absorveEvidence ( - varNodes[i]->varId(), varNodes[i]->getEvidence()); - } - } - } - } -} - - - -void -VarElim::findEliminationOrder (const VarIds& vids) -{ - elimOrder_ = ElimGraph::getEliminationOrder (factorList_, vids); -} - - - -void -VarElim::processFactorList (const VarIds& vids) -{ - totalFactorSize_ = 0; - largestFactorSize_ = 0; - for (size_t i = 0; i < elimOrder_.size(); i++) { - if (Globals::verbosity >= 2) { - if (Globals::verbosity >= 3) { - Util::printDashedLine(); - printActiveFactors(); - } - cout << "-> summing out " ; - cout << fg.getVarNode (elimOrder_[i])->label() << endl; - } - eliminate (elimOrder_[i]); - } - - Factor* finalFactor = new Factor(); - for (size_t i = 0; i < factorList_.size(); i++) { - if (factorList_[i]) { - finalFactor->multiply (*factorList_[i]); - delete factorList_[i]; - factorList_[i] = 0; - } - } - - VarIds unobservedVids; - for (size_t i = 0; i < vids.size(); i++) { - if (fg.getVarNode (vids[i])->hasEvidence() == false) { - unobservedVids.push_back (vids[i]); - } - } - - finalFactor->reorderArguments (unobservedVids); - finalFactor->normalize(); - factorList_.push_back (finalFactor); - if (Globals::verbosity > 0) { - cout << "total factor size: " << totalFactorSize_ << endl; - cout << "largest factor size: " << largestFactorSize_ << endl; - cout << endl; - } -} - - - -void -VarElim::eliminate (VarId elimVar) -{ - Factor* result = 0; - vector& idxs = varFactors_.find (elimVar)->second; - for (size_t i = 0; i < idxs.size(); i++) { - size_t idx = idxs[i]; - if (factorList_[idx]) { - if (result == 0) { - result = new Factor (*factorList_[idx]); - } else { - result->multiply (*factorList_[idx]); - } - delete factorList_[idx]; - factorList_[idx] = 0; - } - } - totalFactorSize_ += result->size(); - if (result->size() > largestFactorSize_) { - largestFactorSize_ = result->size(); - } - if (result != 0 && result->nrArguments() != 1) { - result->sumOut (elimVar); - factorList_.push_back (result); - const VarIds& resultVarIds = result->arguments(); - for (size_t i = 0; i < resultVarIds.size(); i++) { - vector& idxs = - varFactors_.find (resultVarIds[i])->second; - idxs.push_back (factorList_.size() - 1); - } - } -} - - - -void -VarElim::printActiveFactors (void) -{ - for (size_t i = 0; i < factorList_.size(); i++) { - if (factorList_[i] != 0) { - cout << factorList_[i]->getLabel() << " " ; - cout << factorList_[i]->params() << endl; - } - } -} - diff --git a/packages/CLPBN/horus2/VarElim.h b/packages/CLPBN/horus2/VarElim.h deleted file mode 100644 index fe1327fc0..000000000 --- a/packages/CLPBN/horus2/VarElim.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef HORUS_VARELIM_H -#define HORUS_VARELIM_H - -#include "unordered_map" - -#include "GroundSolver.h" -#include "FactorGraph.h" -#include "Horus.h" - - -using namespace std; - - -class VarElim : public GroundSolver -{ - public: - VarElim (const FactorGraph& fg) : GroundSolver (fg) { } - - ~VarElim (void); - - Params solveQuery (VarIds); - - void printSolverFlags (void) const; - - private: - void createFactorList (void); - - void absorveEvidence (void); - - void findEliminationOrder (const VarIds&); - - void processFactorList (const VarIds&); - - void eliminate (VarId); - - void printActiveFactors (void); - - Factors factorList_; - VarIds elimOrder_; - unsigned largestFactorSize_; - unsigned totalFactorSize_; - unordered_map> varFactors_; -}; - -#endif // HORUS_VARELIM_H - diff --git a/packages/CLPBN/horus2/WeightedBp.cpp b/packages/CLPBN/horus2/WeightedBp.cpp deleted file mode 100644 index d8a32a246..000000000 --- a/packages/CLPBN/horus2/WeightedBp.cpp +++ /dev/null @@ -1,288 +0,0 @@ -#include "WeightedBp.h" - - -WeightedBp::~WeightedBp (void) -{ - for (size_t i = 0; i < links_.size(); i++) { - delete links_[i]; - } - links_.clear(); -} - - - -Params -WeightedBp::getPosterioriOf (VarId vid) -{ - if (runned_ == false) { - runSolver(); - } - VarNode* var = fg.getVarNode (vid); - assert (var != 0); - Params probs; - if (var->hasEvidence()) { - probs.resize (var->range(), LogAware::noEvidence()); - probs[var->getEvidence()] = LogAware::withEvidence(); - } else { - probs.resize (var->range(), LogAware::multIdenty()); - const BpLinks& links = ninf(var)->getLinks(); - if (Globals::logDomain) { - for (size_t i = 0; i < links.size(); i++) { - WeightedLink* l = static_cast (links[i]); - probs += l->powMessage(); - } - LogAware::normalize (probs); - Util::exp (probs); - } else { - for (size_t i = 0; i < links.size(); i++) { - WeightedLink* l = static_cast (links[i]); - probs *= l->powMessage(); - } - LogAware::normalize (probs); - } - } - return probs; -} - - - -void -WeightedBp::createLinks (void) -{ - if (Globals::verbosity > 0) { - cout << "compressed factor graph contains " ; - cout << fg.nrVarNodes() << " variables and " ; - cout << fg.nrFacNodes() << " factors " << endl; - cout << endl; - } - const FacNodes& facNodes = fg.facNodes(); - for (size_t i = 0; i < facNodes.size(); i++) { - const VarNodes& neighs = facNodes[i]->neighbors(); - for (size_t j = 0; j < neighs.size(); j++) { - if (Globals::verbosity > 1) { - cout << "creating link " ; - cout << facNodes[i]->getLabel(); - cout << " -- " ; - cout << neighs[j]->label(); - cout << " idx=" << j << ", weight=" << weights_[i][j] << endl; - } - links_.push_back (new WeightedLink ( - facNodes[i], neighs[j], j, weights_[i][j])); - } - } - if (Globals::verbosity > 1) { - cout << endl; - } -} - - - -void -WeightedBp::maxResidualSchedule (void) -{ - if (nIters_ == 1) { - for (size_t i = 0; i < links_.size(); i++) { - calculateMessage (links_[i]); - SortedOrder::iterator it = sortedOrder_.insert (links_[i]); - linkMap_.insert (make_pair (links_[i], it)); - if (Globals::verbosity >= 1) { - cout << "calculating " << links_[i]->toString() << endl; - } - } - return; - } - - for (size_t c = 0; c < links_.size(); c++) { - if (Globals::verbosity > 1) { - cout << endl << "current residuals:" << endl; - for (SortedOrder::iterator it = sortedOrder_.begin(); - it != sortedOrder_.end(); ++it) { - cout << " " << setw (30) << left << (*it)->toString(); - cout << "residual = " << (*it)->residual() << endl; - } - } - - SortedOrder::iterator it = sortedOrder_.begin(); - BpLink* link = *it; - if (Globals::verbosity >= 1) { - cout << "updating " << (*sortedOrder_.begin())->toString() << endl; - } - if (link->residual() < BpOptions::accuracy) { - return; - } - link->updateMessage(); - link->clearResidual(); - sortedOrder_.erase (it); - linkMap_.find (link)->second = sortedOrder_.insert (link); - - // update the messages that depend on message source --> destin - const FacNodes& factorNeighbors = link->varNode()->neighbors(); - for (size_t i = 0; i < factorNeighbors.size(); i++) { - const BpLinks& links = ninf(factorNeighbors[i])->getLinks(); - for (size_t j = 0; j < links.size(); j++) { - if (links[j]->varNode() != link->varNode()) { - if (Globals::verbosity > 1) { - cout << " calculating " << links[j]->toString() << endl; - } - calculateMessage (links[j]); - BpLinkMap::iterator iter = linkMap_.find (links[j]); - sortedOrder_.erase (iter->second); - iter->second = sortedOrder_.insert (links[j]); - } - } - } - // in counting bp, the message that a variable X sends to - // to a factor F depends on the message that F sent to the X - const BpLinks& links = ninf(link->facNode())->getLinks(); - for (size_t i = 0; i < links.size(); i++) { - if (links[i]->varNode() != link->varNode()) { - if (Globals::verbosity > 1) { - cout << " calculating " << links[i]->toString() << endl; - } - calculateMessage (links[i]); - BpLinkMap::iterator iter = linkMap_.find (links[i]); - sortedOrder_.erase (iter->second); - iter->second = sortedOrder_.insert (links[i]); - } - } - } -} - - - -void -WeightedBp::calcFactorToVarMsg (BpLink* _link) -{ - WeightedLink* link = static_cast (_link); - FacNode* src = link->facNode(); - const VarNode* dst = link->varNode(); - const BpLinks& links = ninf(src)->getLinks(); - // calculate the product of messages that were sent - // to factor `src', except from var `dst' - unsigned reps = 1; - unsigned msgSize = Util::sizeExpected (src->factor().ranges()); - Params msgProduct (msgSize, LogAware::multIdenty()); - if (Globals::logDomain) { - for (size_t i = links.size(); i-- > 0; ) { - const WeightedLink* l = static_cast (links[i]); - if ( ! (l->varNode() == dst && l->index() == link->index())) { - if (Constants::SHOW_BP_CALCS) { - cout << " message from " << links[i]->varNode()->label(); - cout << ": " ; - } - Util::apply_n_times (msgProduct, getVarToFactorMsg (links[i]), - reps, std::plus()); - if (Constants::SHOW_BP_CALCS) { - cout << endl; - } - } - reps *= links[i]->varNode()->range(); - } - } else { - for (size_t i = links.size(); i-- > 0; ) { - const WeightedLink* l = static_cast (links[i]); - if ( ! (l->varNode() == dst && l->index() == link->index())) { - if (Constants::SHOW_BP_CALCS) { - cout << " message from " << links[i]->varNode()->label(); - cout << ": " ; - } - Util::apply_n_times (msgProduct, getVarToFactorMsg (links[i]), - reps, std::multiplies()); - if (Constants::SHOW_BP_CALCS) { - cout << endl; - } - } - reps *= links[i]->varNode()->range(); - } - } - Factor result (src->factor().arguments(), - src->factor().ranges(), msgProduct); - assert (msgProduct.size() == src->factor().size()); - if (Globals::logDomain) { - result.params() += src->factor().params(); - } else { - result.params() *= src->factor().params(); - } - if (Constants::SHOW_BP_CALCS) { - cout << " message product: " << msgProduct << endl; - cout << " original factor: " << src->factor().params() << endl; - cout << " factor product: " << result.params() << endl; - } - result.sumOutAllExceptIndex (link->index()); - if (Constants::SHOW_BP_CALCS) { - cout << " marginalized: " << result.params() << endl; - } - link->nextMessage() = result.params(); - LogAware::normalize (link->nextMessage()); - if (Constants::SHOW_BP_CALCS) { - cout << " curr msg: " << link->message() << endl; - cout << " next msg: " << link->nextMessage() << endl; - } -} - - - -Params -WeightedBp::getVarToFactorMsg (const BpLink* _link) const -{ - const WeightedLink* link = static_cast (_link); - const VarNode* src = link->varNode(); - const FacNode* dst = link->facNode(); - Params msg; - if (src->hasEvidence()) { - msg.resize (src->range(), LogAware::noEvidence()); - double value = link->message()[src->getEvidence()]; - if (Constants::SHOW_BP_CALCS) { - msg[src->getEvidence()] = value; - cout << msg << "^" << link->weight() << "-1" ; - } - msg[src->getEvidence()] = LogAware::pow (value, link->weight() - 1); - } else { - msg = link->message(); - if (Constants::SHOW_BP_CALCS) { - cout << msg << "^" << link->weight() << "-1" ; - } - LogAware::pow (msg, link->weight() - 1); - } - const BpLinks& links = ninf(src)->getLinks(); - if (Globals::logDomain) { - for (size_t i = 0; i < links.size(); i++) { - WeightedLink* l = static_cast (links[i]); - if ( ! (l->facNode() == dst && l->index() == link->index())) { - msg += l->powMessage(); - } - } - } else { - for (size_t i = 0; i < links.size(); i++) { - WeightedLink* l = static_cast (links[i]); - if ( ! (l->facNode() == dst && l->index() == link->index())) { - msg *= l->powMessage(); - if (Constants::SHOW_BP_CALCS) { - cout << " x " << l->nextMessage() << "^" << link->weight(); - } - } - } - } - if (Constants::SHOW_BP_CALCS) { - cout << " = " << msg; - } - return msg; -} - - - -void -WeightedBp::printLinkInformation (void) const -{ - for (size_t i = 0; i < links_.size(); i++) { - WeightedLink* l = static_cast (links_[i]); - cout << l->toString() << ":" << endl; - cout << " curr msg = " << l->message() << endl; - cout << " next msg = " << l->nextMessage() << endl; - cout << " pow msg = " << l->powMessage() << endl; - cout << " index = " << l->index() << endl; - cout << " weight = " << l->weight() << endl; - cout << " residual = " << l->residual() << endl; - } -} - diff --git a/packages/CLPBN/horus2/WeightedBp.h b/packages/CLPBN/horus2/WeightedBp.h deleted file mode 100644 index 7794fd509..000000000 --- a/packages/CLPBN/horus2/WeightedBp.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef HORUS_WEIGHTEDBP_H -#define HORUS_WEIGHTEDBP_H - -#include "BeliefProp.h" - -class WeightedLink : public BpLink -{ - public: - WeightedLink (FacNode* fn, VarNode* vn, size_t idx, unsigned weight) - : BpLink (fn, vn), index_(idx), weight_(weight), - pwdMsg_(vn->range(), LogAware::one()) { } - - size_t index (void) const { return index_; } - - unsigned weight (void) const { return weight_; } - - const Params& powMessage (void) const { return pwdMsg_; } - - void updateMessage (void) - { - pwdMsg_ = *nextMsg_; - swap (currMsg_, nextMsg_); - LogAware::pow (pwdMsg_, weight_); - } - - private: - size_t index_; - unsigned weight_; - Params pwdMsg_; -}; - - - -class WeightedBp : public BeliefProp -{ - public: - WeightedBp (const FactorGraph& fg, - const vector>& weights) - : BeliefProp (fg), weights_(weights) { } - - ~WeightedBp (void); - - Params getPosterioriOf (VarId); - - private: - - void createLinks (void); - - void maxResidualSchedule (void); - - void calcFactorToVarMsg (BpLink*); - - Params getVarToFactorMsg (const BpLink*) const; - - void printLinkInformation (void) const; - - vector> weights_; -}; - -#endif // HORUS_WEIGHTEDBP_H -