From a8926fe38b70e66862b4783f18f814ec479598bb Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Mon, 22 Oct 2012 23:01:13 +0100 Subject: [PATCH 01/52] inital code for lifted knowledge compilation --- packages/CLPBN/horus/LiftedCircuit.cpp | 266 ++++++++++++++++++++++++ packages/CLPBN/horus/LiftedCircuit.h | 137 +++++++++++++ packages/CLPBN/horus/LiftedWCNF.cpp | 270 +++++++++++++++++++++++++ packages/CLPBN/horus/LiftedWCNF.h | 129 ++++++++++++ packages/CLPBN/horus/Makefile.in | 12 +- 5 files changed, 811 insertions(+), 3 deletions(-) create mode 100644 packages/CLPBN/horus/LiftedCircuit.cpp create mode 100644 packages/CLPBN/horus/LiftedCircuit.h create mode 100644 packages/CLPBN/horus/LiftedWCNF.cpp create mode 100644 packages/CLPBN/horus/LiftedWCNF.h diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp new file mode 100644 index 000000000..a805f806c --- /dev/null +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -0,0 +1,266 @@ +#include + +#include "LiftedCircuit.h" + + +LiftedCircuit::LiftedCircuit (const LiftedWCNF* lwcnf) + : lwcnf_(lwcnf) +{ + root_ = 0; + Clauses ccc = lwcnf->clauses(); + //ccc.erase (ccc.begin() + 3, ccc.end()); + //Clause c2 = ccc.front(); + //c2.removeLiteralByIndex (1); + //ccc.push_back (c2); + + + //compile (&root_, lwcnf->clauses()); + compile (&root_, ccc); + cout << "done compiling..." << endl; + printToDot(); +} + + + +void +LiftedCircuit::printToDot (void) +{ + const char* fileName = "circuit.dot" ; + ofstream out (fileName); + if (!out.is_open()) { + cerr << "error: cannot open file to write at " ; + cerr << "BayesBallGraph::exportToDotFile()" << endl; + abort(); + } + out << "digraph {" << endl; + out << "ranksep=1" << endl; + printToDot (root_, out); + out << "}" << endl; + out.close(); +} + + + +void +LiftedCircuit::compile ( + CircuitNode** follow, + const Clauses& clauses) +{ + if (clauses.empty()) { + *follow = new TrueNode (); + return; + } + + if (clauses.size() == 1 && clauses[0].isUnit()) { + *follow = new LeafNode (clauses[0]); + return; + } + + if (tryUnitPropagation (follow, clauses)) { + return; + } + + if (tryIndependence (follow, clauses)) { + return; + } + + if (tryShannonDecomposition (follow, clauses)) { + return; + } + + *follow = new FailNode (clauses); + +} + + + +bool +LiftedCircuit::tryUnitPropagation ( + CircuitNode** follow, + const Clauses& clauses) +{ + for (size_t i = 0; i < clauses.size(); i++) { + if (clauses[i].isUnit()) { + Clauses newClauses; + for (size_t j = 0; j < clauses.size(); j++) { + if (i != j) { + LiteralId lid = clauses[i].literals()[0].lid(); + if (clauses[i].literals()[0].isPositive()) { + if (clauses[j].containsPositiveLiteral (lid) == false) { + Clause newClause = clauses[j]; + newClause.removeNegativeLiterals (lid); + newClauses.push_back (newClause); + } + } + if (clauses[i].literals()[0].isNegative()) { + if (clauses[j].containsNegativeLiteral (lid) == false) { + Clause newClause = clauses[j]; + newClause.removePositiveLiterals (lid); + newClauses.push_back (newClause); + } + } + } + } + stringstream explanation; + explanation << " UP of " << clauses[i]; + AndNode* andNode = new AndNode (clauses, explanation.str()); + compile (andNode->leftFollow(), {clauses[i]}); + compile (andNode->rightFollow(), newClauses); + (*follow) = andNode; + return true; + } + } + return false; +} + + + +bool +LiftedCircuit::tryIndependence ( + CircuitNode** follow, + const Clauses& clauses) +{ + if (clauses.size() == 1) { + return false; + } + for (size_t i = 0; i < clauses.size(); i++) { + bool indep = true; + TinySet lids1 = clauses[i].lidSet(); + for (size_t j = 0; j < clauses.size(); j++) { + TinySet lids2 = clauses[j].lidSet(); + if (((lids1 & lids2).empty() == false) && i != j) { + indep = false; + break; + } + } + if (indep == true) { + Clauses newClauses = clauses; + newClauses.erase (newClauses.begin() + i); + stringstream explanation; + explanation << " independence" ; + AndNode* andNode = new AndNode (clauses, explanation.str()); + compile (andNode->leftFollow(), {clauses[i]}); + compile (andNode->rightFollow(), newClauses); + (*follow) = andNode; + return true; + } + } + return false; +} + + + +bool +LiftedCircuit::tryShannonDecomposition ( + CircuitNode** follow, + const Clauses& 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())) { + Literal posLit (literals[j], false); + Literal negLit (literals[j], true); + ConstraintTree* ct1 = new ConstraintTree (*clauses[i].constr()); + ConstraintTree* ct2 = new ConstraintTree (*clauses[i].constr()); + Clause c1 (ct1); + Clause c2 (ct2); + c1.addLiteral (posLit); + c2.addLiteral (negLit); + Clauses leftClauses = { c1 }; + Clauses rightClauses = { c2 }; + leftClauses.insert (leftClauses.end(), clauses.begin(), clauses.end()); + rightClauses.insert (rightClauses.end(), clauses.begin(), clauses.end()); + stringstream explanation; + explanation << " SD on " << literals[j]; + OrNode* orNode = new OrNode (clauses, explanation.str()); + (*follow) = orNode; + compile (orNode->leftFollow(), leftClauses); + compile (orNode->rightFollow(), rightClauses); + return true; + } + } + } + return false; +} + + + +string +LiftedCircuit::escapeNode (const CircuitNode* node) const +{ + stringstream ss; + ss << "\"" << node << "\"" ; + return ss.str(); +} + + + +void +LiftedCircuit::printToDot (CircuitNode* node, ofstream& os) +{ + assert (node != 0); + static unsigned nrAndNodes = 0; + static unsigned nrOrNodes = 0; + + if (dynamic_cast(node) != 0) { + nrAndNodes ++; + AndNode* casted = dynamic_cast(node); + os << escapeNode (node) << " [shape=box,label=\"" ; + const Clauses& clauses = node->clauses(); + for (size_t i = 0; i < clauses.size(); i++) { + os << clauses[i] << "\\n" ; + } + os << "\"]" ; + os << endl; + os << "and" << nrAndNodes << " [label=\"∧\"]" << endl; + os << '"' << node << '"' << " -> " << "and" << nrAndNodes; + os << " [label=\"" << node->explanation() << "\"]" << endl; + os << "and" << nrAndNodes << " -> " ; + os << escapeNode (*casted->leftFollow()) << endl; + os << "and" << nrAndNodes << " -> " ; + os << escapeNode (*casted->rightFollow()) << endl; + printToDot (*casted->leftFollow(), os); + printToDot (*casted->rightFollow(), os); + } else if (dynamic_cast(node) != 0) { + nrOrNodes ++; + OrNode* casted = dynamic_cast(node); + os << escapeNode (node) << " [shape=box,label=\"" ; + const Clauses& clauses = node->clauses(); + for (size_t i = 0; i < clauses.size(); i++) { + os << clauses[i] << "\\n" ; + } + os << "\"]" ; + os << endl; + os << "or" << nrOrNodes << " [label=\"∨\"]" << endl; + os << '"' << node << '"' << " -> " << "or" << nrOrNodes; + os << " [label=\"" << node->explanation() << "\"]" << endl; + os << "or" << nrOrNodes << " -> " ; + os << escapeNode (*casted->leftFollow()) << endl; + os << "or" << nrOrNodes << " -> " ; + os << escapeNode (*casted->rightFollow()) << endl; + printToDot (*casted->leftFollow(), os); + printToDot (*casted->rightFollow(), os); + } else if (dynamic_cast(node) != 0) { + os << escapeNode (node) << " [shape=box,label=\"" ; + os << node->clauses()[0] << "\\n" ; + os << "\"]" ; + os << endl; + } else if (dynamic_cast(node) != 0) { + os << escapeNode (node); + os << " [shape=box,label=\"⊤\"]" ; + os << endl; + } else if (dynamic_cast(node) != 0) { + os << escapeNode (node); + os << " [shape=box,style=filled,fillcolor=red,label=\"" ; + const Clauses& clauses = node->clauses(); + for (size_t i = 0; i < clauses.size(); i++) { + os << clauses[i] << "\\n" ; + } + os << "\"]" ; + os << endl; + } else { + cout << "something really failled" << endl; + } +} + diff --git a/packages/CLPBN/horus/LiftedCircuit.h b/packages/CLPBN/horus/LiftedCircuit.h new file mode 100644 index 000000000..dfd74d82d --- /dev/null +++ b/packages/CLPBN/horus/LiftedCircuit.h @@ -0,0 +1,137 @@ +#ifndef HORUS_LIFTEDCIRCUIT_H +#define HORUS_LIFTEDCIRCUIT_H + +#include "LiftedWCNF.h" + + +class CircuitNode +{ + public: + CircuitNode (const Clauses& clauses, string explanation = "") + : clauses_(clauses), explanation_(explanation) { } + + const Clauses& clauses (void) { return clauses_; } + + virtual double weight (void) const { return 0; } + + string explanation (void) const { return explanation_; } + + private: + Clauses clauses_; + string explanation_; +}; + + + +class AndNode : public CircuitNode +{ + public: + AndNode (const Clauses& clauses, string explanation = "") + : CircuitNode (clauses, explanation), + leftFollow_(0), rightFollow_(0) { } + + CircuitNode** leftFollow (void) { return &leftFollow_; } + CircuitNode** rightFollow (void) { return &rightFollow_; } + private: + CircuitNode* leftFollow_; + CircuitNode* rightFollow_; +}; + + + +class OrNode : public CircuitNode +{ + public: + OrNode (const Clauses& clauses, string explanation = "") + : CircuitNode (clauses, explanation), + leftFollow_(0), rightFollow_(0) { } + + CircuitNode** leftFollow (void) { return &leftFollow_; } + CircuitNode** rightFollow (void) { return &rightFollow_; } + private: + CircuitNode* leftFollow_; + CircuitNode* rightFollow_; +}; + + + +class SetAndNode : public CircuitNode +{ + public: + private: + CircuitNode* follow_; +}; + + + +class SetOrNode : public CircuitNode +{ + public: + private: + CircuitNode* follow_; +}; + + + +class IncExclNode : public CircuitNode +{ + public: + private: + CircuitNode* xFollow_; + CircuitNode* yFollow_; + CircuitNode* zFollow_; +}; + + + +class LeafNode : public CircuitNode +{ + public: + LeafNode (const Clause& clause) : CircuitNode ({clause}) { } + private: +}; + + + +class TrueNode : public CircuitNode +{ + public: + TrueNode () : CircuitNode ({}) { } + private: +}; + + + + +class FailNode : public CircuitNode +{ + public: + FailNode (const Clauses& clauses) : CircuitNode (clauses) { } + private: +}; + + + +class LiftedCircuit +{ + public: + LiftedCircuit (const LiftedWCNF* lwcnf); + + void printToDot (void); + + private: + + void compile (CircuitNode** follow, const Clauses& clauses); + + bool tryUnitPropagation (CircuitNode** follow, const Clauses& clauses); + bool tryIndependence (CircuitNode** follow, const Clauses& clauses); + bool tryShannonDecomposition (CircuitNode** follow, const Clauses& clauses); + + string escapeNode (const CircuitNode*) const; + void printToDot (CircuitNode* node, ofstream&); + + CircuitNode* root_; + const LiftedWCNF* lwcnf_; +}; + +#endif // HORUS_LIFTEDCIRCUIT_H diff --git a/packages/CLPBN/horus/LiftedWCNF.cpp b/packages/CLPBN/horus/LiftedWCNF.cpp new file mode 100644 index 000000000..2e67c38eb --- /dev/null +++ b/packages/CLPBN/horus/LiftedWCNF.cpp @@ -0,0 +1,270 @@ +#include "LiftedWCNF.h" +#include "ConstraintTree.h" +#include "Indexer.h" + + +bool +Literal::isGround (ConstraintTree* constr) const +{ + if (logVars_.size() == 0) { + return true; + } + LogVarSet singletons = constr->singletons(); + return singletons.contains (logVars_); +} + + + +std::ostream& operator<< (ostream &os, const Literal& lit) +{ + lit.negated_ ? os << "¬" : os << "" ; + lit.weight_ < 0.0 ? os << "λ" : os << "Θ" ; + os << lit.lid_ ; + if (lit.logVars_.empty() == false) { + os << "(" ; + for (size_t i = 0; i < lit.logVars_.size(); i++) { + if (i != 0) os << ","; + os << lit.logVars_[i]; + } + os << ")" ; + } + return os; +} + + + +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 +{ + for (size_t i = 0; i < literals_.size(); i++) { + if (literals_[i].lid() == lid && literals_[i].isPositive()) { + return true; + } + } + return false; +} + + + +bool +Clause::containsNegativeLiteral (LiteralId lid) const +{ + for (size_t i = 0; i < literals_.size(); i++) { + if (literals_[i].lid() == lid && literals_[i].isNegative()) { + return true; + } + } + return false; +} + + + +void +Clause::removeLiterals (LiteralId lid) +{ + size_t i = 0; + while (i != literals_.size()) { + if (literals_[i].lid() == lid) { + literals_.erase (literals_.begin() + i); + } else { + i ++; + } + } +} + + + +void +Clause::removePositiveLiterals (LiteralId lid) +{ + size_t i = 0; + while (i != literals_.size()) { + if (literals_[i].lid() == lid && literals_[i].isPositive()) { + literals_.erase (literals_.begin() + i); + } else { + i ++; + } + } +} + + + +void +Clause::removeNegativeLiterals (LiteralId lid) +{ + size_t i = 0; + while (i != literals_.size()) { + if (literals_[i].lid() == lid && literals_[i].isNegative()) { + literals_.erase (literals_.begin() + i); + } else { + i ++; + } + } +} + + + +TinySet +Clause::lidSet (void) const +{ + TinySet lidSet; + for (size_t i = 0; i < literals_.size(); i++) { + lidSet.insert (literals_[i].lid()); + } + return lidSet; +} + + + +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]; + } + if (clause.ct_->empty() == false) { + ConstraintTree copy (*clause.ct_); + copy.moveToTop (copy.logVarSet().elements()); + os << " | " << copy.tupleSet(); + } + return os; +} + + + +LiftedWCNF::LiftedWCNF (const ParfactorList& pfList) + : pfList_(pfList), freeLiteralId_(0) +{ + addIndicatorClauses (pfList); + addParameterClauses (pfList); + printFormulasToIndicators(); + printClauses(); +} + + + +LiftedWCNF::~LiftedWCNF (void) +{ + +} + + + +void +LiftedWCNF::addIndicatorClauses (const ParfactorList& pfList) +{ + ParfactorList::const_iterator it = pfList.begin(); + set allGroups; + 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()); + ConstraintTree* tempConstr = new ConstraintTree (*(*it)->constr()); + tempConstr->project (formulas[i].logVars()); + Clause 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 = new ConstraintTree (*(*it)->constr()); + tempConstr2->project (formulas[i].logVars()); + Clause clause2 (tempConstr2); + clause2.addAndNegateLiteral (Literal (clause.literals()[j])); + clause2.addAndNegateLiteral (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_; + + Clause clause1 ((*it)->constr()); + + for (unsigned i = 0; i < groups.size(); i++) { + LiteralId lid = getLiteralId (groups[i], indexer[i]); + + clause1.addAndNegateLiteral (Literal (lid, (*it)->argument(i).logVars())); + + Clause tempClause ((*it)->constr()); + tempClause.addAndNegateLiteral (Literal (paramVarLid, LogVars(), 1.0)); + tempClause.addLiteral (Literal (lid, (*it)->argument(i).logVars())); + clauses_.push_back (tempClause); + } + clause1.addLiteral (Literal (paramVarLid, LogVars(), 1.0)); + clauses_.push_back (clause1); + freeLiteralId_ ++; + ++ indexer; + } + ++ it; + } +} + + +void +LiftedWCNF::printClauses (void) const +{ + for (unsigned i = 0; i < clauses_.size(); i++) { + cout << clauses_[i] << endl; + } +} + + + +void +LiftedWCNF::printFormulasToIndicators (void) const +{ + 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()); + tempCt.project (formulas[i].logVars()); + cout << tempCt.tupleSet(); + cout << " indicators => " ; + vector indicators = + (map_.find (formulas[i].group()))->second; + cout << indicators << endl; + } + } + ++ it; + } +} + diff --git a/packages/CLPBN/horus/LiftedWCNF.h b/packages/CLPBN/horus/LiftedWCNF.h new file mode 100644 index 000000000..e829a1fba --- /dev/null +++ b/packages/CLPBN/horus/LiftedWCNF.h @@ -0,0 +1,129 @@ +#ifndef HORUS_LIFTEDWCNF_H +#define HORUS_LIFTEDWCNF_H + +#include "ParfactorList.h" + +using namespace std; + +typedef long LiteralId; + +class ConstraintTree; + + +class Literal +{ + public: + Literal (LiteralId lid, const LogVars& lvs, double w = -1.0) : + lid_(lid), logVars_(lvs), weight_(w), negated_(false) { } + + Literal (const Literal& lit, bool negated) : + lid_(lit.lid_), logVars_(lit.logVars_), weight_(lit.weight_), negated_(negated) { } + + LiteralId lid (void) const { return lid_; } + + double weight (void) const { return weight_; } + + void negate (void) { negated_ = !negated_; } + + bool isPositive (void) const { return negated_ == false; } + + bool isNegative (void) const { return negated_; } + + bool isGround (ConstraintTree* constr) const; + + friend std::ostream& operator<< (ostream &os, const Literal& lit); + + private: + LiteralId lid_; + LogVars logVars_; + double weight_; + bool negated_; +}; + +typedef vector Literals; + + +class Clause +{ + public: + Clause (ConstraintTree* ct) : ct_(ct) { } + + void addLiteral (const Literal& l) { literals_.push_back (l); } + + void addAndNegateLiteral (const Literal& l) + { + literals_.push_back (l); + literals_.back().negate(); + } + + bool containsLiteral (LiteralId lid) const; + + bool containsPositiveLiteral (LiteralId lid) const; + + bool containsNegativeLiteral (LiteralId lid) const; + + void removeLiterals (LiteralId lid); + + void removePositiveLiterals (LiteralId lid); + + void removeNegativeLiterals (LiteralId lid); + + const vector& literals (void) const { return literals_; } + + void removeLiteralByIndex (size_t idx) { literals_.erase (literals_.begin() + idx); } + + ConstraintTree* constr (void) const { return ct_; } + + ConstraintTree* constr (void) { return ct_; } + + bool isUnit (void) const { return literals_.size() == 1; } + + TinySet lidSet (void) const; + + friend std::ostream& operator<< (ostream &os, const Clause& clause); + + private: + vector literals_; + ConstraintTree* ct_; +}; + + + +typedef vector Clauses; + + + +class LiftedWCNF +{ + public: + LiftedWCNF (const ParfactorList& pfList); + + ~LiftedWCNF (void); + + const Clauses& clauses (void) const { return clauses_; } + + void printClauses (void) const; + + void printFormulasToIndicators (void) const; + + private: + void addIndicatorClauses (const ParfactorList& pfList); + + void addParameterClauses (const ParfactorList& pfList); + + LiteralId getLiteralId (PrvGroup prvGroup, unsigned range) + { + assert (Util::contains (map_, prvGroup)); + return map_[prvGroup][range]; + } + + Clauses clauses_; + + unordered_map> map_; + + const ParfactorList& pfList_; + + LiteralId freeLiteralId_; +}; + +#endif // HORUS_LIFTEDWCNF_H diff --git a/packages/CLPBN/horus/Makefile.in b/packages/CLPBN/horus/Makefile.in index 8aa12d4c5..10a99f782 100644 --- a/packages/CLPBN/horus/Makefile.in +++ b/packages/CLPBN/horus/Makefile.in @@ -23,10 +23,10 @@ CC=@CC@ CXX=@CXX@ # normal -CXXFLAGS= -std=c++0x @SHLIB_CXXFLAGS@ $(YAP_EXTRAS) $(DEFS) -D_YAP_NOT_INSTALLED_=1 -I$(srcdir) -I../../.. -I$(srcdir)/../../../include @CPPFLAGS@ -DNDEBUG +#CXXFLAGS= -std=c++0x @SHLIB_CXXFLAGS@ $(YAP_EXTRAS) $(DEFS) -D_YAP_NOT_INSTALLED_=1 -I$(srcdir) -I../../.. -I$(srcdir)/../../../include @CPPFLAGS@ -DNDEBUG # debug -#CXXFLAGS= -std=c++0x @SHLIB_CXXFLAGS@ $(YAP_EXTRAS) $(DEFS) -D_YAP_NOT_INSTALLED_=1 -I$(srcdir) -I../../.. -I$(srcdir)/../../../include @CPPFLAGS@ -g -O0 -Wextra +CXXFLAGS= -std=c++0x @SHLIB_CXXFLAGS@ $(YAP_EXTRAS) $(DEFS) -D_YAP_NOT_INSTALLED_=1 -I$(srcdir) -I../../.. -I$(srcdir)/../../../include @CPPFLAGS@ -g -O0 -Wextra # @@ -57,8 +57,10 @@ HEADERS = \ $(srcdir)/Horus.h \ $(srcdir)/Indexer.h \ $(srcdir)/LiftedBp.h \ + $(srcdir)/LiftedCircuit.h \ $(srcdir)/LiftedUtils.h \ $(srcdir)/LiftedVe.h \ + $(srcdir)/LiftedWCNF.h \ $(srcdir)/Parfactor.h \ $(srcdir)/ParfactorList.h \ $(srcdir)/ProbFormula.h \ @@ -82,8 +84,10 @@ CPP_SOURCES = \ $(srcdir)/HorusCli.cpp \ $(srcdir)/HorusYap.cpp \ $(srcdir)/LiftedBp.cpp \ + $(srcdir)/LiftedCircuit.h \ $(srcdir)/LiftedUtils.cpp \ $(srcdir)/LiftedVe.cpp \ + $(srcdir)/LiftedWCNF.cpp \ $(srcdir)/Parfactor.cpp \ $(srcdir)/ParfactorList.cpp \ $(srcdir)/ProbFormula.cpp \ @@ -91,7 +95,7 @@ CPP_SOURCES = \ $(srcdir)/Util.cpp \ $(srcdir)/Var.cpp \ $(srcdir)/VarElim.cpp \ - $(srcdir)/WeightedBp.cpp \ + $(srcdir)/WeightedBp.cpp OBJS = \ BayesBall.o \ @@ -105,8 +109,10 @@ OBJS = \ Histogram.o \ HorusYap.o \ LiftedBp.o \ + LiftedCircuit.o \ LiftedUtils.o \ LiftedVe.o \ + LiftedWCNF.o \ ProbFormula.o \ Parfactor.o \ ParfactorList.o \ From 0cfc64d0680ffd28107b796b56c646c2a9ec1c68 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Wed, 24 Oct 2012 16:24:49 +0100 Subject: [PATCH 02/52] update TODO --- packages/CLPBN/horus/TODO | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/CLPBN/horus/TODO b/packages/CLPBN/horus/TODO index 9f2dfa108..c2afafb0b 100644 --- a/packages/CLPBN/horus/TODO +++ b/packages/CLPBN/horus/TODO @@ -1,3 +1,4 @@ +- Handle formulas like f(X,X) - Find a way to decrease the time required to find an elimination order for variable elimination From eac6b954a85b613a327d90abe684525f291fa75c Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Wed, 24 Oct 2012 21:22:49 +0100 Subject: [PATCH 03/52] add inital smoothing of the circuit --- packages/CLPBN/horus/LiftedCircuit.cpp | 236 ++++++++++++++++++++----- packages/CLPBN/horus/LiftedCircuit.h | 102 +++++++---- packages/CLPBN/horus/LiftedWCNF.cpp | 29 ++- packages/CLPBN/horus/LiftedWCNF.h | 9 +- 4 files changed, 295 insertions(+), 81 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index a805f806c..4332e5584 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -8,24 +8,32 @@ LiftedCircuit::LiftedCircuit (const LiftedWCNF* lwcnf) { root_ = 0; Clauses ccc = lwcnf->clauses(); - //ccc.erase (ccc.begin() + 3, ccc.end()); + ccc.erase (ccc.begin() + 5, ccc.end()); //Clause c2 = ccc.front(); //c2.removeLiteralByIndex (1); //ccc.push_back (c2); - //compile (&root_, lwcnf->clauses()); compile (&root_, ccc); cout << "done compiling..." << endl; - printToDot(); + exportToGraphViz("circuit.dot"); + smoothCircuit(); + exportToGraphViz("smooth.dot"); } void -LiftedCircuit::printToDot (void) +LiftedCircuit::smoothCircuit (void) +{ + smoothCircuit (root_); +} + + + +void +LiftedCircuit::exportToGraphViz (const char* fileName) { - const char* fileName = "circuit.dot" ; ofstream out (fileName); if (!out.is_open()) { cerr << "error: cannot open file to write at " ; @@ -34,7 +42,7 @@ LiftedCircuit::printToDot (void) } out << "digraph {" << endl; out << "ranksep=1" << endl; - printToDot (root_, out); + exportToGraphViz (root_, out); out << "}" << endl; out.close(); } @@ -52,7 +60,18 @@ LiftedCircuit::compile ( } if (clauses.size() == 1 && clauses[0].isUnit()) { + static int count = 0; count ++; *follow = new LeafNode (clauses[0]); + if (count == 1) { + Clause c (new ConstraintTree({})); + c.addLiteral (Literal (100,{})); + *follow = new LeafNode (c); + } + if (count == 2) { + Clause c (new ConstraintTree({})); + c.addLiteral (Literal (101,{})); + *follow = new LeafNode (c); + } return; } @@ -64,7 +83,7 @@ LiftedCircuit::compile ( return; } - if (tryShannonDecomposition (follow, clauses)) { + if (tryShannonDecomp (follow, clauses)) { return; } @@ -104,8 +123,8 @@ LiftedCircuit::tryUnitPropagation ( stringstream explanation; explanation << " UP of " << clauses[i]; AndNode* andNode = new AndNode (clauses, explanation.str()); - compile (andNode->leftFollow(), {clauses[i]}); - compile (andNode->rightFollow(), newClauses); + compile (andNode->leftBranch(), {clauses[i]}); + compile (andNode->rightBranch(), newClauses); (*follow) = andNode; return true; } @@ -139,8 +158,8 @@ LiftedCircuit::tryIndependence ( stringstream explanation; explanation << " independence" ; AndNode* andNode = new AndNode (clauses, explanation.str()); - compile (andNode->leftFollow(), {clauses[i]}); - compile (andNode->rightFollow(), newClauses); + compile (andNode->leftBranch(), {clauses[i]}); + compile (andNode->rightBranch(), newClauses); (*follow) = andNode; return true; } @@ -151,7 +170,7 @@ LiftedCircuit::tryIndependence ( bool -LiftedCircuit::tryShannonDecomposition ( +LiftedCircuit::tryShannonDecomp ( CircuitNode** follow, const Clauses& clauses) { @@ -175,8 +194,8 @@ LiftedCircuit::tryShannonDecomposition ( explanation << " SD on " << literals[j]; OrNode* orNode = new OrNode (clauses, explanation.str()); (*follow) = orNode; - compile (orNode->leftFollow(), leftClauses); - compile (orNode->rightFollow(), rightClauses); + compile (orNode->leftBranch(), leftClauses); + compile (orNode->rightBranch(), rightClauses); return true; } } @@ -186,6 +205,113 @@ LiftedCircuit::tryShannonDecomposition ( +TinySet +LiftedCircuit::smoothCircuit (CircuitNode* node) +{ + assert (node != 0); + TinySet propagatingLids; + + switch (getCircuitNodeType (node)) { + + case CircuitNodeType::OR_NODE: { + OrNode* casted = dynamic_cast(node); + TinySet lids1 = smoothCircuit (*casted->leftBranch()); + TinySet lids2 = smoothCircuit (*casted->rightBranch()); + TinySet missingLeft = lids2 - lids1; + TinySet missingRight = lids1 - lids2; + if (missingLeft.empty() == false) { + Clauses clauses; + for (size_t i = 0; i < missingLeft.size(); i++) { + Clause c = lwcnf_->createClauseForLiteral (missingLeft[i]); + c.addAndNegateLiteral (c.literals()[0]); + clauses.push_back (c); + } + SmoothNode* smoothNode = new SmoothNode (clauses); + CircuitNode** prev = casted->leftBranch(); + string explanation = " smoothing" ; + AndNode* andNode = new AndNode ((*prev)->clauses(), smoothNode, *prev, explanation); + *prev = andNode; + } + if (missingRight.empty() == false) { + Clauses clauses; + for (size_t i = 0; i < missingRight.size(); i++) { + Clause c = lwcnf_->createClauseForLiteral (missingRight[i]); + c.addAndNegateLiteral (c.literals()[0]); + clauses.push_back (c); + } + SmoothNode* smoothNode = new SmoothNode (clauses); + CircuitNode** prev = casted->rightBranch(); + string explanation = " smoothing" ; + AndNode* andNode = new AndNode ((*prev)->clauses(), smoothNode, *prev, explanation); + *prev = andNode; + } + propagatingLids |= lids1; + propagatingLids |= lids2; + break; + } + + case CircuitNodeType::AND_NODE: { + AndNode* casted = dynamic_cast(node); + TinySet lids1 = smoothCircuit (*casted->leftBranch()); + TinySet lids2 = smoothCircuit (*casted->rightBranch()); + propagatingLids |= lids1; + propagatingLids |= lids2; + break; + } + + case CircuitNodeType::SET_OR_NODE: { + // TODO + } + + case CircuitNodeType::SET_AND_NODE: { + // TODO + } + + case CircuitNodeType::INC_EXC_NODE: { + // TODO + } + + case CircuitNodeType::LEAF_NODE: { + propagatingLids.insert (node->clauses()[0].literals()[0].lid()); + } + + // case CircuitNodeType::SMOOTH_NODE: + // case CircuitNodeType::TRUE_NODE: + // case CircuitNodeType::FAIL_NODE: + + default: + break; + } + + return propagatingLids; +} + + + +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::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::FAIL_NODE; + } else { + assert (false); + } + return type; +} + + + string LiftedCircuit::escapeNode (const CircuitNode* node) const { @@ -197,19 +323,41 @@ LiftedCircuit::escapeNode (const CircuitNode* node) const void -LiftedCircuit::printToDot (CircuitNode* node, ofstream& os) +LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) { assert (node != 0); static unsigned nrAndNodes = 0; static unsigned nrOrNodes = 0; - if (dynamic_cast(node) != 0) { - nrAndNodes ++; - AndNode* casted = dynamic_cast(node); - os << escapeNode (node) << " [shape=box,label=\"" ; + if (dynamic_cast(node) != 0) { + OrNode* casted = dynamic_cast(node); const Clauses& clauses = node->clauses(); + if (clauses.empty() == false) { + os << escapeNode (node) << " [shape=box,label=\"" ; for (size_t i = 0; i < clauses.size(); i++) { - os << clauses[i] << "\\n" ; + if (i != 0) os << "\\n" ; + os << clauses[i]; + } + os << "\"]" ; + os << endl; + } + os << "or" << nrOrNodes << " [label=\"∨\"]" << endl; + os << '"' << node << '"' << " -> " << "or" << nrOrNodes; + os << " [label=\"" << node->explanation() << "\"]" << endl; + os << "or" << nrOrNodes << " -> " ; + os << escapeNode (*casted->leftBranch()) << endl; + os << "or" << nrOrNodes << " -> " ; + os << escapeNode (*casted->rightBranch()) << endl; + nrOrNodes ++; + exportToGraphViz (*casted->leftBranch(), os); + exportToGraphViz (*casted->rightBranch(), os); + } else if (dynamic_cast(node) != 0) { + AndNode* casted = dynamic_cast(node); + const Clauses& clauses = node->clauses(); + os << escapeNode (node) << " [shape=box,label=\"" ; + for (size_t i = 0; i < clauses.size(); i++) { + if (i != 0) os << "\\n" ; + os << clauses[i]; } os << "\"]" ; os << endl; @@ -217,33 +365,26 @@ LiftedCircuit::printToDot (CircuitNode* node, ofstream& os) os << '"' << node << '"' << " -> " << "and" << nrAndNodes; os << " [label=\"" << node->explanation() << "\"]" << endl; os << "and" << nrAndNodes << " -> " ; - os << escapeNode (*casted->leftFollow()) << endl; + os << escapeNode (*casted->leftBranch()) << endl; os << "and" << nrAndNodes << " -> " ; - os << escapeNode (*casted->rightFollow()) << endl; - printToDot (*casted->leftFollow(), os); - printToDot (*casted->rightFollow(), os); - } else if (dynamic_cast(node) != 0) { - nrOrNodes ++; - OrNode* casted = dynamic_cast(node); - os << escapeNode (node) << " [shape=box,label=\"" ; - const Clauses& clauses = node->clauses(); - for (size_t i = 0; i < clauses.size(); i++) { - os << clauses[i] << "\\n" ; - } + os << escapeNode (*casted->rightBranch()) << endl; + nrAndNodes ++; + exportToGraphViz (*casted->leftBranch(), os); + exportToGraphViz (*casted->rightBranch(), os); + } else if (dynamic_cast(node) != 0) { + os << escapeNode (node); + os << " [shape=box,label=\"" ; + os << node->clauses()[0]; os << "\"]" ; os << endl; - os << "or" << nrOrNodes << " [label=\"∨\"]" << endl; - os << '"' << node << '"' << " -> " << "or" << nrOrNodes; - os << " [label=\"" << node->explanation() << "\"]" << endl; - os << "or" << nrOrNodes << " -> " ; - os << escapeNode (*casted->leftFollow()) << endl; - os << "or" << nrOrNodes << " -> " ; - os << escapeNode (*casted->rightFollow()) << endl; - printToDot (*casted->leftFollow(), os); - printToDot (*casted->rightFollow(), os); - } else if (dynamic_cast(node) != 0) { - os << escapeNode (node) << " [shape=box,label=\"" ; - os << node->clauses()[0] << "\\n" ; + } else if (dynamic_cast(node) != 0) { + os << escapeNode (node); + os << " [shape=box,style=filled,fillcolor=chartreuse,label=\"" ; + const Clauses& clauses = node->clauses(); + for (size_t i = 0; i < clauses.size(); i++) { + if (i != 0) os << "\\n" ; + os << clauses[i]; + } os << "\"]" ; os << endl; } else if (dynamic_cast(node) != 0) { @@ -252,15 +393,16 @@ LiftedCircuit::printToDot (CircuitNode* node, ofstream& os) os << endl; } else if (dynamic_cast(node) != 0) { os << escapeNode (node); - os << " [shape=box,style=filled,fillcolor=red,label=\"" ; + os << " [shape=box,style=filled,fillcolor=brown1,label=\"" ; const Clauses& clauses = node->clauses(); for (size_t i = 0; i < clauses.size(); i++) { - os << clauses[i] << "\\n" ; + if (i != 0) os << "\\n" ; + os << clauses[i]; } os << "\"]" ; os << endl; } else { - cout << "something really failled" << endl; + assert (false); } } diff --git a/packages/CLPBN/horus/LiftedCircuit.h b/packages/CLPBN/horus/LiftedCircuit.h index dfd74d82d..e386e78d5 100644 --- a/packages/CLPBN/horus/LiftedCircuit.h +++ b/packages/CLPBN/horus/LiftedCircuit.h @@ -4,6 +4,20 @@ #include "LiftedWCNF.h" +enum CircuitNodeType { + OR_NODE, + AND_NODE, + SET_OR_NODE, + SET_AND_NODE, + INC_EXC_NODE, + LEAF_NODE, + SMOOTH_NODE, + TRUE_NODE, + FAIL_NODE +}; + + + class CircuitNode { public: @@ -23,34 +37,49 @@ class CircuitNode -class AndNode : public CircuitNode -{ - public: - AndNode (const Clauses& clauses, string explanation = "") - : CircuitNode (clauses, explanation), - leftFollow_(0), rightFollow_(0) { } - - CircuitNode** leftFollow (void) { return &leftFollow_; } - CircuitNode** rightFollow (void) { return &rightFollow_; } - private: - CircuitNode* leftFollow_; - CircuitNode* rightFollow_; -}; - - - class OrNode : public CircuitNode { public: OrNode (const Clauses& clauses, string explanation = "") : CircuitNode (clauses, explanation), - leftFollow_(0), rightFollow_(0) { } + leftBranch_(0), rightBranch_(0) { } - CircuitNode** leftFollow (void) { return &leftFollow_; } - CircuitNode** rightFollow (void) { return &rightFollow_; } + CircuitNode** leftBranch (void) { return &leftBranch_; } + CircuitNode** rightBranch (void) { return &rightBranch_; } private: - CircuitNode* leftFollow_; - CircuitNode* rightFollow_; + CircuitNode* leftBranch_; + CircuitNode* rightBranch_; +}; + + + +class AndNode : public CircuitNode +{ + public: + AndNode (const Clauses& clauses, string explanation = "") + : CircuitNode (clauses, explanation), + leftBranch_(0), rightBranch_(0) { } + + AndNode ( + const Clauses& clauses, + CircuitNode* leftBranch, + CircuitNode* rightBranch, + string explanation = "") + : CircuitNode (clauses, explanation), + leftBranch_(leftBranch), rightBranch_(rightBranch) { } + + AndNode ( + CircuitNode* leftBranch, + CircuitNode* rightBranch, + string explanation = "") + : CircuitNode ({}, explanation), + leftBranch_(leftBranch), rightBranch_(rightBranch) { } + + CircuitNode** leftBranch (void) { return &leftBranch_; } + CircuitNode** rightBranch (void) { return &rightBranch_; } + private: + CircuitNode* leftBranch_; + CircuitNode* rightBranch_; }; @@ -88,7 +117,14 @@ class LeafNode : public CircuitNode { public: LeafNode (const Clause& clause) : CircuitNode ({clause}) { } - private: +}; + + + +class SmoothNode : public CircuitNode +{ + public: + SmoothNode (const Clauses& clauses) : CircuitNode (clauses) { } }; @@ -97,7 +133,6 @@ class TrueNode : public CircuitNode { public: TrueNode () : CircuitNode ({}) { } - private: }; @@ -107,7 +142,6 @@ class FailNode : public CircuitNode { public: FailNode (const Clauses& clauses) : CircuitNode (clauses) { } - private: }; @@ -117,21 +151,29 @@ class LiftedCircuit public: LiftedCircuit (const LiftedWCNF* lwcnf); - void printToDot (void); + void smoothCircuit (void); + + void exportToGraphViz (const char*); private: void compile (CircuitNode** follow, const Clauses& clauses); bool tryUnitPropagation (CircuitNode** follow, const Clauses& clauses); - bool tryIndependence (CircuitNode** follow, const Clauses& clauses); - bool tryShannonDecomposition (CircuitNode** follow, const Clauses& clauses); - - string escapeNode (const CircuitNode*) const; - void printToDot (CircuitNode* node, ofstream&); + bool tryIndependence (CircuitNode** follow, const Clauses& clauses); + bool tryShannonDecomp (CircuitNode** follow, const Clauses& clauses); + + TinySet smoothCircuit (CircuitNode* node); + + CircuitNodeType getCircuitNodeType (const CircuitNode* node) const; + + string escapeNode (const CircuitNode* node) const; + + void exportToGraphViz (CircuitNode* node, ofstream&); CircuitNode* root_; const LiftedWCNF* lwcnf_; }; #endif // HORUS_LIFTEDCIRCUIT_H + diff --git a/packages/CLPBN/horus/LiftedWCNF.cpp b/packages/CLPBN/horus/LiftedWCNF.cpp index 2e67c38eb..ac08bbbe0 100644 --- a/packages/CLPBN/horus/LiftedWCNF.cpp +++ b/packages/CLPBN/horus/LiftedWCNF.cpp @@ -150,7 +150,7 @@ LiftedWCNF::LiftedWCNF (const ParfactorList& pfList) { addIndicatorClauses (pfList); addParameterClauses (pfList); - printFormulasToIndicators(); + printFormulaIndicators(); printClauses(); } @@ -163,6 +163,31 @@ LiftedWCNF::~LiftedWCNF (void) +Clause +LiftedWCNF::createClauseForLiteral (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 = new ConstraintTree (*clauses_[i].constr()); + ct->project (literals[j].logVars()); + Clause clause (ct); + clause.addLiteral (literals[j]); + return clause; + } + } + } + // FIXME + Clause c (new ConstraintTree({})); + c.addLiteral (Literal (lid,{})); + return c; + //assert (false); + //return Clause (0); +} + + + void LiftedWCNF::addIndicatorClauses (const ParfactorList& pfList) { @@ -245,7 +270,7 @@ LiftedWCNF::printClauses (void) const void -LiftedWCNF::printFormulasToIndicators (void) const +LiftedWCNF::printFormulaIndicators (void) const { set allGroups; ParfactorList::const_iterator it = pfList_.begin(); diff --git a/packages/CLPBN/horus/LiftedWCNF.h b/packages/CLPBN/horus/LiftedWCNF.h index e829a1fba..f71582b42 100644 --- a/packages/CLPBN/horus/LiftedWCNF.h +++ b/packages/CLPBN/horus/LiftedWCNF.h @@ -20,6 +20,8 @@ class Literal lid_(lit.lid_), logVars_(lit.logVars_), weight_(lit.weight_), negated_(negated) { } LiteralId lid (void) const { return lid_; } + + LogVars logVars (void) const { return logVars_; } double weight (void) const { return weight_; } @@ -102,9 +104,11 @@ class LiftedWCNF const Clauses& clauses (void) const { return clauses_; } + Clause createClauseForLiteral (LiteralId lid) const; + void printClauses (void) const; - void printFormulasToIndicators (void) const; + void printFormulaIndicators (void) const; private: void addIndicatorClauses (const ParfactorList& pfList); @@ -119,7 +123,7 @@ class LiftedWCNF Clauses clauses_; - unordered_map> map_; + unordered_map> map_; const ParfactorList& pfList_; @@ -127,3 +131,4 @@ class LiftedWCNF }; #endif // HORUS_LIFTEDWCNF_H + From 68ef63207fc4fd324a7b9ee4e3cb646d39005fa5 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Thu, 25 Oct 2012 12:22:52 +0100 Subject: [PATCH 04/52] initial support for weighted model countign --- packages/CLPBN/horus/LiftedCircuit.cpp | 255 +++++++++++++++++-------- packages/CLPBN/horus/LiftedCircuit.h | 18 +- packages/CLPBN/horus/LiftedWCNF.cpp | 75 ++++++-- packages/CLPBN/horus/LiftedWCNF.h | 14 +- 4 files changed, 266 insertions(+), 96 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index 4332e5584..f3b27d4b9 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -3,22 +3,92 @@ #include "LiftedCircuit.h" +double +OrNode::weight (void) const +{ + double lw = leftBranch_->weight(); + double rw = rightBranch_->weight(); + return Globals::logDomain ? Util::logSum (lw, rw) : lw + rw; +} + + + +double +AndNode::weight (void) const +{ + double lw = leftBranch_->weight(); + double rw = rightBranch_->weight(); + return Globals::logDomain ? lw + rw : lw * rw; +} + + + +double +LeafNode::weight (void) const +{ + assert (clauses().size() == 1); + assert (clauses()[0].isUnit()); + Clause c = clauses()[0]; + double weight = c.literals()[0].weight(); + unsigned nrGroundings = c.constr()->size(); + assert (nrGroundings != 0); + double www = Globals::logDomain + ? weight * nrGroundings + : std::pow (weight, nrGroundings); + + cout << "leaf w: " << www << endl; + + return Globals::logDomain + ? weight * nrGroundings + : std::pow (weight, nrGroundings); +} + + + +double +SmoothNode::weight (void) const +{ + Clauses cs = clauses(); + double totalWeight = LogAware::multIdenty(); + for (size_t i = 0; i < cs.size(); i++) { + double posWeight = cs[i].literals()[0].weight(); + double negWeight = cs[i].literals()[1].weight(); + unsigned nrGroundings = cs[i].constr()->size(); + 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(); +} + + + LiftedCircuit::LiftedCircuit (const LiftedWCNF* lwcnf) : lwcnf_(lwcnf) { root_ = 0; Clauses ccc = lwcnf->clauses(); - ccc.erase (ccc.begin() + 5, ccc.end()); + //ccc.erase (ccc.begin() + 5, ccc.end()); //Clause c2 = ccc.front(); //c2.removeLiteralByIndex (1); //ccc.push_back (c2); //compile (&root_, lwcnf->clauses()); compile (&root_, ccc); - cout << "done compiling..." << endl; exportToGraphViz("circuit.dot"); smoothCircuit(); exportToGraphViz("smooth.dot"); + cout << "WEIGHTED MODEL COUNT = " << getWeightedModelCount() << endl; } @@ -31,6 +101,14 @@ LiftedCircuit::smoothCircuit (void) +double +LiftedCircuit::getWeightedModelCount (void) const +{ + return root_->weight(); +} + + + void LiftedCircuit::exportToGraphViz (const char* fileName) { @@ -63,14 +141,14 @@ LiftedCircuit::compile ( static int count = 0; count ++; *follow = new LeafNode (clauses[0]); if (count == 1) { - Clause c (new ConstraintTree({})); - c.addLiteral (Literal (100,{})); - *follow = new LeafNode (c); + // Clause c (new ConstraintTree({})); + // c.addLiteral (Literal (100,{})); + // *follow = new LeafNode (c); } if (count == 2) { - Clause c (new ConstraintTree({})); - c.addLiteral (Literal (101,{})); - *follow = new LeafNode (c); + // Clause c (new ConstraintTree({})); + // c.addLiteral (Literal (101,{})); + // *follow = new LeafNode (c); } return; } @@ -326,83 +404,104 @@ void LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) { assert (node != 0); + static unsigned nrAndNodes = 0; static unsigned nrOrNodes = 0; - if (dynamic_cast(node) != 0) { - OrNode* casted = dynamic_cast(node); - const Clauses& clauses = node->clauses(); - if (clauses.empty() == false) { - os << escapeNode (node) << " [shape=box,label=\"" ; - for (size_t i = 0; i < clauses.size(); i++) { - if (i != 0) os << "\\n" ; - os << clauses[i]; + switch (getCircuitNodeType (node)) { + + case OR_NODE: { + OrNode* casted = dynamic_cast(node); + const Clauses& clauses = node->clauses(); + if (clauses.empty() == false) { + os << escapeNode (node) << " [shape=box,label=\"" ; + for (size_t i = 0; i < clauses.size(); i++) { + if (i != 0) os << "\\n" ; + os << clauses[i]; + } + os << "\"]" ; + os << endl; + } + os << "or" << nrOrNodes << " [label=\"∨\"]" << endl; + os << '"' << node << '"' << " -> " << "or" << nrOrNodes; + os << " [label=\"" << node->explanation() << "\"]" << endl; + os << "or" << nrOrNodes << " -> " ; + os << escapeNode (*casted->leftBranch()) << endl; + os << "or" << nrOrNodes << " -> " ; + os << escapeNode (*casted->rightBranch()) << endl; + nrOrNodes ++; + exportToGraphViz (*casted->leftBranch(), os); + exportToGraphViz (*casted->rightBranch(), os); + break; } - os << "\"]" ; - os << endl; + + case AND_NODE: { + AndNode* casted = dynamic_cast(node); + const Clauses& clauses = node->clauses(); + os << escapeNode (node) << " [shape=box,label=\"" ; + for (size_t i = 0; i < clauses.size(); i++) { + if (i != 0) os << "\\n" ; + os << clauses[i]; + } + os << "\"]" ; + os << endl; + os << "and" << nrAndNodes << " [label=\"∧\"]" << endl; + os << '"' << node << '"' << " -> " << "and" << nrAndNodes; + os << " [label=\"" << node->explanation() << "\"]" << endl; + os << "and" << nrAndNodes << " -> " ; + os << escapeNode (*casted->leftBranch()) << endl; + os << "and" << nrAndNodes << " -> " ; + os << escapeNode (*casted->rightBranch()) << endl; + nrAndNodes ++; + exportToGraphViz (*casted->leftBranch(), os); + exportToGraphViz (*casted->rightBranch(), os); + break; } - os << "or" << nrOrNodes << " [label=\"∨\"]" << endl; - os << '"' << node << '"' << " -> " << "or" << nrOrNodes; - os << " [label=\"" << node->explanation() << "\"]" << endl; - os << "or" << nrOrNodes << " -> " ; - os << escapeNode (*casted->leftBranch()) << endl; - os << "or" << nrOrNodes << " -> " ; - os << escapeNode (*casted->rightBranch()) << endl; - nrOrNodes ++; - exportToGraphViz (*casted->leftBranch(), os); - exportToGraphViz (*casted->rightBranch(), os); - } else if (dynamic_cast(node) != 0) { - AndNode* casted = dynamic_cast(node); - const Clauses& clauses = node->clauses(); - os << escapeNode (node) << " [shape=box,label=\"" ; - for (size_t i = 0; i < clauses.size(); i++) { - if (i != 0) os << "\\n" ; - os << clauses[i]; + + case LEAF_NODE: { + os << escapeNode (node); + os << " [shape=box,label=\"" ; + os << node->clauses()[0]; + os << "\"]" ; + os << endl; + break; } - os << "\"]" ; - os << endl; - os << "and" << nrAndNodes << " [label=\"∧\"]" << endl; - os << '"' << node << '"' << " -> " << "and" << nrAndNodes; - os << " [label=\"" << node->explanation() << "\"]" << endl; - os << "and" << nrAndNodes << " -> " ; - os << escapeNode (*casted->leftBranch()) << endl; - os << "and" << nrAndNodes << " -> " ; - os << escapeNode (*casted->rightBranch()) << endl; - nrAndNodes ++; - exportToGraphViz (*casted->leftBranch(), os); - exportToGraphViz (*casted->rightBranch(), os); - } else if (dynamic_cast(node) != 0) { - os << escapeNode (node); - os << " [shape=box,label=\"" ; - os << node->clauses()[0]; - os << "\"]" ; - os << endl; - } else if (dynamic_cast(node) != 0) { - os << escapeNode (node); - os << " [shape=box,style=filled,fillcolor=chartreuse,label=\"" ; - const Clauses& clauses = node->clauses(); - for (size_t i = 0; i < clauses.size(); i++) { - if (i != 0) os << "\\n" ; - os << clauses[i]; + + case SMOOTH_NODE: { + os << escapeNode (node); + os << " [shape=box,style=filled,fillcolor=chartreuse,label=\"" ; + const Clauses& clauses = node->clauses(); + for (size_t i = 0; i < clauses.size(); i++) { + if (i != 0) os << "\\n" ; + os << clauses[i]; + } + os << "\"]" ; + os << endl; + break; } - os << "\"]" ; - os << endl; - } else if (dynamic_cast(node) != 0) { - os << escapeNode (node); - os << " [shape=box,label=\"⊤\"]" ; - os << endl; - } else if (dynamic_cast(node) != 0) { - os << escapeNode (node); - os << " [shape=box,style=filled,fillcolor=brown1,label=\"" ; - const Clauses& clauses = node->clauses(); - for (size_t i = 0; i < clauses.size(); i++) { - if (i != 0) os << "\\n" ; - os << clauses[i]; + + case TRUE_NODE: { + os << escapeNode (node); + os << " [shape=box,label=\"⊤\"]" ; + os << endl; + break; } - os << "\"]" ; - os << endl; - } else { - assert (false); - } + + case FAIL_NODE: { + os << escapeNode (node); + os << " [shape=box,style=filled,fillcolor=brown1,label=\"" ; + const Clauses& clauses = node->clauses(); + for (size_t i = 0; i < clauses.size(); i++) { + if (i != 0) os << "\\n" ; + os << clauses[i]; + } + os << "\"]" ; + os << endl; + break; + } + + default: + assert (false); + } } diff --git a/packages/CLPBN/horus/LiftedCircuit.h b/packages/CLPBN/horus/LiftedCircuit.h index e386e78d5..839d14a70 100644 --- a/packages/CLPBN/horus/LiftedCircuit.h +++ b/packages/CLPBN/horus/LiftedCircuit.h @@ -24,7 +24,9 @@ class CircuitNode CircuitNode (const Clauses& clauses, string explanation = "") : clauses_(clauses), explanation_(explanation) { } - const Clauses& clauses (void) { return clauses_; } + const Clauses& clauses (void) const { return clauses_; } + + Clauses clauses (void) { return clauses_; } virtual double weight (void) const { return 0; } @@ -43,6 +45,8 @@ class OrNode : public CircuitNode OrNode (const Clauses& clauses, string explanation = "") : CircuitNode (clauses, explanation), leftBranch_(0), rightBranch_(0) { } + + double weight (void) const; CircuitNode** leftBranch (void) { return &leftBranch_; } CircuitNode** rightBranch (void) { return &rightBranch_; } @@ -74,6 +78,8 @@ class AndNode : public CircuitNode string explanation = "") : CircuitNode ({}, explanation), leftBranch_(leftBranch), rightBranch_(rightBranch) { } + + double weight (void) const; CircuitNode** leftBranch (void) { return &leftBranch_; } CircuitNode** rightBranch (void) { return &rightBranch_; } @@ -117,6 +123,8 @@ class LeafNode : public CircuitNode { public: LeafNode (const Clause& clause) : CircuitNode ({clause}) { } + + double weight (void) const; }; @@ -125,6 +133,8 @@ class SmoothNode : public CircuitNode { public: SmoothNode (const Clauses& clauses) : CircuitNode (clauses) { } + + double weight (void) const; }; @@ -133,6 +143,8 @@ class TrueNode : public CircuitNode { public: TrueNode () : CircuitNode ({}) { } + + double weight (void) const; }; @@ -153,8 +165,10 @@ class LiftedCircuit void smoothCircuit (void); + double getWeightedModelCount (void) const; + void exportToGraphViz (const char*); - + private: void compile (CircuitNode** follow, const Clauses& clauses); diff --git a/packages/CLPBN/horus/LiftedWCNF.cpp b/packages/CLPBN/horus/LiftedWCNF.cpp index ac08bbbe0..df2efd59e 100644 --- a/packages/CLPBN/horus/LiftedWCNF.cpp +++ b/packages/CLPBN/horus/LiftedWCNF.cpp @@ -150,8 +150,15 @@ LiftedWCNF::LiftedWCNF (const ParfactorList& pfList) { addIndicatorClauses (pfList); addParameterClauses (pfList); + cout << "FORMULA INDICATORS:" << endl; printFormulaIndicators(); + cout << endl; + cout << "WEIGHTS:" << endl; + printWeights(); + cout << endl; + cout << "CLAUSES:" << endl; printClauses(); + cout << endl; } @@ -237,6 +244,8 @@ LiftedWCNF::addParameterClauses (const ParfactorList& pfList) while (indexer.valid()) { LiteralId paramVarLid = freeLiteralId_; + double weight = (**it)[indexer]; + Clause clause1 ((*it)->constr()); for (unsigned i = 0; i < groups.size(); i++) { @@ -245,11 +254,11 @@ LiftedWCNF::addParameterClauses (const ParfactorList& pfList) clause1.addAndNegateLiteral (Literal (lid, (*it)->argument(i).logVars())); Clause tempClause ((*it)->constr()); - tempClause.addAndNegateLiteral (Literal (paramVarLid, LogVars(), 1.0)); + tempClause.addAndNegateLiteral (Literal (paramVarLid, 1.0)); tempClause.addLiteral (Literal (lid, (*it)->argument(i).logVars())); clauses_.push_back (tempClause); } - clause1.addLiteral (Literal (paramVarLid, LogVars(), 1.0)); + clause1.addLiteral (Literal (paramVarLid, weight)); clauses_.push_back (clause1); freeLiteralId_ ++; ++ indexer; @@ -259,16 +268,6 @@ LiftedWCNF::addParameterClauses (const ParfactorList& pfList) } -void -LiftedWCNF::printClauses (void) const -{ - for (unsigned i = 0; i < clauses_.size(); i++) { - cout << clauses_[i] << endl; - } -} - - - void LiftedWCNF::printFormulaIndicators (void) const { @@ -293,3 +292,55 @@ LiftedWCNF::printFormulaIndicators (void) const } } + + +void +LiftedWCNF::printWeights (void) const +{ + for (LiteralId i = 0; i < freeLiteralId_; i++) { + + bool found = false; + for (size_t j = 0; j < clauses_.size(); j++) { + Literals literals = clauses_[j].literals(); + for (size_t k = 0; k < literals.size(); k++) { + if (literals[k].lid() == i && literals[k].isPositive()) { + cout << "weight(" << literals[k] << ") = " << literals[k].weight(); + cout << endl; + found = true; + break; + } + } + if (found == true) { + break; + } + } + + found = false; + for (size_t j = 0; j < clauses_.size(); j++) { + Literals literals = clauses_[j].literals(); + for (size_t k = 0; k < literals.size(); k++) { + if (literals[k].lid() == i && literals[k].isNegative()) { + cout << "weight(" << literals[k] << ") = " << literals[k].weight(); + cout << endl; + found = true; + break; + } + } + if (found == true) { + break; + } + } + + } +} + + + +void +LiftedWCNF::printClauses (void) const +{ + for (unsigned i = 0; i < clauses_.size(); i++) { + cout << clauses_[i] << endl; + } +} + diff --git a/packages/CLPBN/horus/LiftedWCNF.h b/packages/CLPBN/horus/LiftedWCNF.h index f71582b42..78a75db4e 100644 --- a/packages/CLPBN/horus/LiftedWCNF.h +++ b/packages/CLPBN/horus/LiftedWCNF.h @@ -13,8 +13,11 @@ class ConstraintTree; class Literal { public: + Literal (LiteralId lid, double w = -1.0) : + lid_(lid), weight_(w), negated_(false) { } + Literal (LiteralId lid, const LogVars& lvs, double w = -1.0) : - lid_(lid), logVars_(lvs), weight_(w), negated_(false) { } + lid_(lid), logVars_(lvs), weight_(w), negated_(false) { } Literal (const Literal& lit, bool negated) : lid_(lit.lid_), logVars_(lit.logVars_), weight_(lit.weight_), negated_(negated) { } @@ -23,7 +26,8 @@ class Literal LogVars logVars (void) const { return logVars_; } - double weight (void) const { return weight_; } + // FIXME not log aware + double weight (void) const { return weight_ < 0.0 ? 1.0 : weight_; } void negate (void) { negated_ = !negated_; } @@ -106,9 +110,11 @@ class LiftedWCNF Clause createClauseForLiteral (LiteralId lid) const; - void printClauses (void) const; - void printFormulaIndicators (void) const; + + void printWeights (void) const; + + void printClauses (void) const; private: void addIndicatorClauses (const ParfactorList& pfList); From d074ca9a8fb36922aaeb03333a1bc2c705191c27 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Sat, 27 Oct 2012 00:13:11 +0100 Subject: [PATCH 05/52] add initial independent partial grounding support --- packages/CLPBN/horus/LiftedCircuit.cpp | 165 ++++++++++++++++++++++--- packages/CLPBN/horus/LiftedCircuit.h | 28 +++-- packages/CLPBN/horus/LiftedWCNF.cpp | 121 ++++++++++++------ packages/CLPBN/horus/LiftedWCNF.h | 23 +++- 4 files changed, 273 insertions(+), 64 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index f3b27d4b9..8b6214428 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -23,6 +23,28 @@ AndNode::weight (void) const +double +SetOrNode::weight (void) const +{ + // TODO + assert (false); + return 0.0; +} + + + + +double +SetAndNode::weight (void) const +{ + unsigned nrGroundings = 2; // FIXME + return Globals::logDomain + ? follow_->weight() * nrGroundings + : std::pow (follow_->weight(), nrGroundings); +} + + + double LeafNode::weight (void) const { @@ -30,13 +52,13 @@ LeafNode::weight (void) const assert (clauses()[0].isUnit()); Clause c = clauses()[0]; double weight = c.literals()[0].weight(); - unsigned nrGroundings = c.constr()->size(); + unsigned nrGroundings = c.constr().size(); assert (nrGroundings != 0); double www = Globals::logDomain ? weight * nrGroundings : std::pow (weight, nrGroundings); - cout << "leaf w: " << www << endl; + cout << "leaf weight(" << clauses()[0].literals()[0] << "): " << www << endl; return Globals::logDomain ? weight * nrGroundings @@ -53,7 +75,7 @@ SmoothNode::weight (void) const for (size_t i = 0; i < cs.size(); i++) { double posWeight = cs[i].literals()[0].weight(); double negWeight = cs[i].literals()[1].weight(); - unsigned nrGroundings = cs[i].constr()->size(); + unsigned nrGroundings = cs[i].constr().size(); if (Globals::logDomain) { totalWeight += (Util::logSum (posWeight, negWeight) * nrGroundings); } else { @@ -130,7 +152,7 @@ LiftedCircuit::exportToGraphViz (const char* fileName) void LiftedCircuit::compile ( CircuitNode** follow, - const Clauses& clauses) + Clauses& clauses) { if (clauses.empty()) { *follow = new TrueNode (); @@ -165,6 +187,15 @@ LiftedCircuit::compile ( return; } + if (tryIndepPartialGrounding (follow, clauses)) { + return; + } + + if (tryGrounding (follow, clauses)) { + return; + } + + // assert (false); *follow = new FailNode (clauses); } @@ -174,7 +205,7 @@ LiftedCircuit::compile ( bool LiftedCircuit::tryUnitPropagation ( CircuitNode** follow, - const Clauses& clauses) + Clauses& clauses) { for (size_t i = 0; i < clauses.size(); i++) { if (clauses[i].isUnit()) { @@ -185,11 +216,14 @@ LiftedCircuit::tryUnitPropagation ( if (clauses[i].literals()[0].isPositive()) { if (clauses[j].containsPositiveLiteral (lid) == false) { Clause newClause = clauses[j]; + //cout << "new j : " << clauses[j] << endl; + //cout << "new clause: " << newClause << endl; + //cout << "clvs: " << clauses[j].constr()->logVars() << endl; newClause.removeNegativeLiterals (lid); newClauses.push_back (newClause); } - } - if (clauses[i].literals()[0].isNegative()) { + } else if (clauses[i].literals()[0].isNegative()) { + //cout << "unit prop of = " << clauses[i].literals()[0] << endl; if (clauses[j].containsNegativeLiteral (lid) == false) { Clause newClause = clauses[j]; newClause.removePositiveLiterals (lid); @@ -201,7 +235,8 @@ LiftedCircuit::tryUnitPropagation ( stringstream explanation; explanation << " UP of " << clauses[i]; AndNode* andNode = new AndNode (clauses, explanation.str()); - compile (andNode->leftBranch(), {clauses[i]}); + Clauses leftClauses = {clauses[i]}; + compile (andNode->leftBranch(), leftClauses); compile (andNode->rightBranch(), newClauses); (*follow) = andNode; return true; @@ -215,7 +250,7 @@ LiftedCircuit::tryUnitPropagation ( bool LiftedCircuit::tryIndependence ( CircuitNode** follow, - const Clauses& clauses) + Clauses& clauses) { if (clauses.size() == 1) { return false; @@ -236,7 +271,8 @@ LiftedCircuit::tryIndependence ( stringstream explanation; explanation << " independence" ; AndNode* andNode = new AndNode (clauses, explanation.str()); - compile (andNode->leftBranch(), {clauses[i]}); + Clauses indepClause = {clauses[i]}; + compile (andNode->leftBranch(), indepClause); compile (andNode->rightBranch(), newClauses); (*follow) = andNode; return true; @@ -250,16 +286,16 @@ LiftedCircuit::tryIndependence ( bool LiftedCircuit::tryShannonDecomp ( CircuitNode** follow, - const Clauses& clauses) + Clauses& 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())) { + if (literals[j].isGround (clauses[i].constr(),clauses[i].ipgLogVars())) { Literal posLit (literals[j], false); Literal negLit (literals[j], true); - ConstraintTree* ct1 = new ConstraintTree (*clauses[i].constr()); - ConstraintTree* ct2 = new ConstraintTree (*clauses[i].constr()); + ConstraintTree ct1 = clauses[i].constr(); + ConstraintTree ct2 = clauses[i].constr(); Clause c1 (ct1); Clause c2 (ct2); c1.addLiteral (posLit); @@ -283,6 +319,72 @@ LiftedCircuit::tryShannonDecomp ( +bool +LiftedCircuit::tryIndepPartialGrounding ( + CircuitNode** follow, + Clauses& clauses) +{ + // assumes that all literals have logical variables + LogVar X = clauses[0].constr().logVars()[0]; + ConstraintTree ct = clauses[0].constr(); + + // FIXME this is so weak ... + ct.project ({X}); + for (size_t i = 0; i < clauses.size(); i++) { + if (clauses[i].constr().logVars().size() == 1) { + if (ct.tupleSet() != clauses[i].constr().tupleSet()) { + return false; + } + } else { + return false; + } + } + + // FIXME this is so broken ... + Clauses newClauses = clauses; + for (size_t i = 0; i < clauses.size(); i++) { + newClauses[i].addIpgLogVar (clauses[i].constr().logVars()[0]); + } + + string explanation = " IPG" ; + SetAndNode* node = new SetAndNode (clauses, explanation); + *follow = node; + compile (node->follow(), newClauses); + return true; +} + + + +bool +LiftedCircuit::tryGrounding ( + CircuitNode** follow, + Clauses& clauses) +{ + return false; + /* + size_t bestClauseIdx = 0; + size_t bestLogVarIdx = 0; + unsigned minNrSymbols = Util::maxUnsigned(); + for (size_t i = 0; i < clauses.size(); i++) { + LogVarSet lvs = clauses[i].constr().logVars(); + ConstraintTree ct = clauses[i].constr(); + for (unsigned j = 0; j < lvs.size(); j++) { + unsigned nrSymbols = ct.nrSymbols (lvs[j]); + if (nrSymbols < minNrSymbols) { + minNrSymbols = nrSymbols; + bestClauseIdx = i; + bestLogVarIdx = j; + } + } + } + LogVar bestLogVar = clauses[bestClauseIdx].constr().logVars()[bestLogVarIdx]; + ConstraintTrees cts = clauses[bestClauseIdx].constr().ground (bestLogVar); + return true; + */ +} + + + TinySet LiftedCircuit::smoothCircuit (CircuitNode* node) { @@ -374,6 +476,10 @@ LiftedCircuit::getCircuitNodeType (const CircuitNode* node) const 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::LEAF_NODE; } else if (dynamic_cast(node) != 0) { @@ -404,9 +510,11 @@ void LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) { assert (node != 0); - + + static unsigned nrOrNodes = 0; static unsigned nrAndNodes = 0; - static unsigned nrOrNodes = 0; + static unsigned nrSetOrNodes = 0; + static unsigned nrSetAndNodes = 0; switch (getCircuitNodeType (node)) { @@ -458,6 +566,31 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) break; } + case SET_OR_NODE: { + nrSetOrNodes ++; + assert (false); // not yet implemented + } + + case SET_AND_NODE: { + SetAndNode* casted = dynamic_cast(node); + const Clauses& clauses = node->clauses(); + os << escapeNode (node) << " [shape=box,label=\"" ; + for (size_t i = 0; i < clauses.size(); i++) { + if (i != 0) os << "\\n" ; + os << clauses[i]; + } + os << "\"]" ; + os << endl; + os << "setand" << nrSetAndNodes << " [label=\"∧(X)\"]" << endl; + os << '"' << node << '"' << " -> " << "setand" << nrSetAndNodes; + os << " [label=\"" << node->explanation() << "\"]" << endl; + os << "setand" << nrSetAndNodes << " -> " ; + os << escapeNode (*casted->follow()) << endl; + nrSetAndNodes ++; + exportToGraphViz (*casted->follow(), os); + break; + } + case LEAF_NODE: { os << escapeNode (node); os << " [shape=box,label=\"" ; diff --git a/packages/CLPBN/horus/LiftedCircuit.h b/packages/CLPBN/horus/LiftedCircuit.h index 839d14a70..435a26517 100644 --- a/packages/CLPBN/horus/LiftedCircuit.h +++ b/packages/CLPBN/horus/LiftedCircuit.h @@ -46,7 +46,7 @@ class OrNode : public CircuitNode : CircuitNode (clauses, explanation), leftBranch_(0), rightBranch_(0) { } - double weight (void) const; + double weight (void) const; CircuitNode** leftBranch (void) { return &leftBranch_; } CircuitNode** rightBranch (void) { return &rightBranch_; } @@ -90,18 +90,30 @@ class AndNode : public CircuitNode -class SetAndNode : public CircuitNode +class SetOrNode : public CircuitNode { public: + SetOrNode (const Clauses& clauses, string explanation = "") + : CircuitNode (clauses, explanation), follow_(0) { } + + double weight (void) const; + + CircuitNode** follow (void) { return &follow_; } private: CircuitNode* follow_; }; -class SetOrNode : public CircuitNode +class SetAndNode : public CircuitNode { public: + SetAndNode (const Clauses& clauses, string explanation = "") + : CircuitNode (clauses, explanation), follow_(0) { } + + double weight (void) const; + + CircuitNode** follow (void) { return &follow_; } private: CircuitNode* follow_; }; @@ -171,11 +183,13 @@ class LiftedCircuit private: - void compile (CircuitNode** follow, const Clauses& clauses); + void compile (CircuitNode** follow, Clauses& clauses); - bool tryUnitPropagation (CircuitNode** follow, const Clauses& clauses); - bool tryIndependence (CircuitNode** follow, const Clauses& clauses); - bool tryShannonDecomp (CircuitNode** follow, const Clauses& clauses); + bool tryUnitPropagation (CircuitNode** follow, Clauses& clauses); + bool tryIndependence (CircuitNode** follow, Clauses& clauses); + bool tryShannonDecomp (CircuitNode** follow, Clauses& clauses); + bool tryIndepPartialGrounding (CircuitNode** follow, Clauses& clauses); + bool tryGrounding (CircuitNode** follow, Clauses& clauses); TinySet smoothCircuit (CircuitNode* node); diff --git a/packages/CLPBN/horus/LiftedWCNF.cpp b/packages/CLPBN/horus/LiftedWCNF.cpp index df2efd59e..4ad651621 100644 --- a/packages/CLPBN/horus/LiftedWCNF.cpp +++ b/packages/CLPBN/horus/LiftedWCNF.cpp @@ -4,30 +4,49 @@ bool -Literal::isGround (ConstraintTree* constr) const +Literal::isGround (ConstraintTree constr, LogVarSet ipgLogVars) const { if (logVars_.size() == 0) { return true; } - LogVarSet singletons = constr->singletons(); - return singletons.contains (logVars_); + LogVarSet lvs (logVars_); + lvs -= ipgLogVars; + return constr.singletons().contains (lvs); +} + + + +string +Literal::toString (LogVarSet ipgLogVars) const +{ + stringstream ss; + negated_ ? ss << "¬" : ss << "" ; + weight_ < 0.0 ? ss << "λ" : ss << "Θ" ; + ss << lid_ ; + if (logVars_.empty() == false) { + ss << "(" ; + for (size_t i = 0; i < logVars_.size(); i++) { + if (i != 0) ss << ","; + 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) { - lit.negated_ ? os << "¬" : os << "" ; - lit.weight_ < 0.0 ? os << "λ" : os << "Θ" ; - os << lit.lid_ ; - if (lit.logVars_.empty() == false) { - os << "(" ; - for (size_t i = 0; i < lit.logVars_.size(); i++) { - if (i != 0) os << ","; - os << lit.logVars_[i]; - } - os << ")" ; - } + os << lit.toString(); return os; } @@ -78,7 +97,7 @@ Clause::removeLiterals (LiteralId lid) size_t i = 0; while (i != literals_.size()) { if (literals_[i].lid() == lid) { - literals_.erase (literals_.begin() + i); + removeLiteral (i); } else { i ++; } @@ -93,7 +112,7 @@ Clause::removePositiveLiterals (LiteralId lid) size_t i = 0; while (i != literals_.size()) { if (literals_[i].lid() == lid && literals_[i].isPositive()) { - literals_.erase (literals_.begin() + i); + removeLiteral (i); } else { i ++; } @@ -108,7 +127,7 @@ Clause::removeNegativeLiterals (LiteralId lid) size_t i = 0; while (i != literals_.size()) { if (literals_[i].lid() == lid && literals_[i].isNegative()) { - literals_.erase (literals_.begin() + i); + removeLiteral (i); } else { i ++; } @@ -129,14 +148,39 @@ Clause::lidSet (void) const +void +Clause::removeLiteral (size_t idx) +{ + LogVarSet lvs (literals_[idx].logVars()); + lvs -= getLogVarSetExcluding (idx); + constr_.remove (lvs); + literals_.erase (literals_.begin() + idx); +} + + + +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<< (ostream &os, const Clause& clause) { for (unsigned i = 0; i < clause.literals_.size(); i++) { if (i != 0) os << " v " ; - os << clause.literals_[i]; + os << clause.literals_[i].toString (clause.ipgLogVars_); } - if (clause.ct_->empty() == false) { - ConstraintTree copy (*clause.ct_); + if (clause.constr_.empty() == false) { + ConstraintTree copy = clause.constr_; copy.moveToTop (copy.logVarSet().elements()); os << " | " << copy.tupleSet(); } @@ -177,8 +221,8 @@ LiftedWCNF::createClauseForLiteral (LiteralId lid) const const Literals& literals = clauses_[i].literals(); for (size_t j = 0; j < literals.size(); j++) { if (literals[j].lid() == lid) { - ConstraintTree* ct = new ConstraintTree (*clauses_[i].constr()); - ct->project (literals[j].logVars()); + ConstraintTree ct = clauses_[i].constr(); + ct.project (literals[j].logVars()); Clause clause (ct); clause.addLiteral (literals[j]); return clause; @@ -186,7 +230,7 @@ LiftedWCNF::createClauseForLiteral (LiteralId lid) const } } // FIXME - Clause c (new ConstraintTree({})); + Clause c (ConstraintTree({})); c.addLiteral (Literal (lid,{})); return c; //assert (false); @@ -205,8 +249,8 @@ LiftedWCNF::addIndicatorClauses (const ParfactorList& pfList) for (size_t i = 0; i < formulas.size(); i++) { if (Util::contains (allGroups, formulas[i].group()) == false) { allGroups.insert (formulas[i].group()); - ConstraintTree* tempConstr = new ConstraintTree (*(*it)->constr()); - tempConstr->project (formulas[i].logVars()); + ConstraintTree tempConstr = *(*it)->constr(); + tempConstr.project (formulas[i].logVars()); Clause clause (tempConstr); vector lids; for (size_t j = 0; j < formulas[i].range(); j++) { @@ -217,8 +261,8 @@ LiftedWCNF::addIndicatorClauses (const ParfactorList& pfList) 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 = new ConstraintTree (*(*it)->constr()); - tempConstr2->project (formulas[i].logVars()); + ConstraintTree tempConstr2 = *(*it)->constr(); + tempConstr2.project (formulas[i].logVars()); Clause clause2 (tempConstr2); clause2.addAndNegateLiteral (Literal (clause.literals()[j])); clause2.addAndNegateLiteral (Literal (clause.literals()[k])); @@ -243,22 +287,27 @@ LiftedWCNF::addParameterClauses (const ParfactorList& pfList) 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 weight = (**it)[indexer]; - Clause clause1 ((*it)->constr()); + Clause clause1 (*(*it)->constr()); for (unsigned i = 0; i < groups.size(); i++) { LiteralId lid = getLiteralId (groups[i], indexer[i]); clause1.addAndNegateLiteral (Literal (lid, (*it)->argument(i).logVars())); - Clause tempClause ((*it)->constr()); - tempClause.addAndNegateLiteral (Literal (paramVarLid, 1.0)); + ConstraintTree ct = *(*it)->constr(); + Clause tempClause (ct); + tempClause.addAndNegateLiteral (Literal (paramVarLid, (*it)->constr()->logVars(), 1.0)); tempClause.addLiteral (Literal (lid, (*it)->argument(i).logVars())); clauses_.push_back (tempClause); } - clause1.addLiteral (Literal (paramVarLid, weight)); + clause1.addLiteral (Literal (paramVarLid, (*it)->constr()->logVars(),weight)); clauses_.push_back (clause1); freeLiteralId_ ++; ++ indexer; @@ -279,7 +328,7 @@ LiftedWCNF::printFormulaIndicators (void) const if (Util::contains (allGroups, formulas[i].group()) == false) { allGroups.insert (formulas[i].group()); cout << formulas[i] << " | " ; - ConstraintTree tempCt (*(*it)->constr()); + ConstraintTree tempCt = *(*it)->constr(); tempCt.project (formulas[i].logVars()); cout << tempCt.tupleSet(); cout << " indicators => " ; @@ -304,7 +353,8 @@ LiftedWCNF::printWeights (void) const Literals literals = clauses_[j].literals(); for (size_t k = 0; k < literals.size(); k++) { if (literals[k].lid() == i && literals[k].isPositive()) { - cout << "weight(" << literals[k] << ") = " << literals[k].weight(); + cout << "weight(" << literals[k] << ") = " ; + cout << literals[k].weight(); cout << endl; found = true; break; @@ -320,7 +370,8 @@ LiftedWCNF::printWeights (void) const Literals literals = clauses_[j].literals(); for (size_t k = 0; k < literals.size(); k++) { if (literals[k].lid() == i && literals[k].isNegative()) { - cout << "weight(" << literals[k] << ") = " << literals[k].weight(); + cout << "weight(" << literals[k] << ") = " ; + cout << literals[k].weight(); cout << endl; found = true; break; diff --git a/packages/CLPBN/horus/LiftedWCNF.h b/packages/CLPBN/horus/LiftedWCNF.h index 78a75db4e..155ec48e8 100644 --- a/packages/CLPBN/horus/LiftedWCNF.h +++ b/packages/CLPBN/horus/LiftedWCNF.h @@ -26,7 +26,7 @@ class Literal LogVars logVars (void) const { return logVars_; } - // FIXME not log aware + // FIXME not log aware :( double weight (void) const { return weight_ < 0.0 ? 1.0 : weight_; } void negate (void) { negated_ = !negated_; } @@ -35,7 +35,9 @@ class Literal bool isNegative (void) const { return negated_; } - bool isGround (ConstraintTree* constr) const; + bool isGround (ConstraintTree constr, LogVarSet ipgLogVars) const; + + string toString (LogVarSet ipgLogVars = LogVarSet()) const; friend std::ostream& operator<< (ostream &os, const Literal& lit); @@ -52,7 +54,7 @@ typedef vector Literals; class Clause { public: - Clause (ConstraintTree* ct) : ct_(ct) { } + Clause (const ConstraintTree& ct) : constr_(ct) { } void addLiteral (const Literal& l) { literals_.push_back (l); } @@ -78,19 +80,28 @@ class Clause void removeLiteralByIndex (size_t idx) { literals_.erase (literals_.begin() + idx); } - ConstraintTree* constr (void) const { return ct_; } + const ConstraintTree& constr (void) const { return constr_; } - ConstraintTree* constr (void) { return ct_; } + ConstraintTree constr (void) { return constr_; } bool isUnit (void) const { return literals_.size() == 1; } + LogVarSet ipgLogVars (void) const { return ipgLogVars_; } + + void addIpgLogVar (LogVar X) { ipgLogVars_.insert (X); } + TinySet lidSet (void) const; friend std::ostream& operator<< (ostream &os, const Clause& clause); private: + void removeLiteral (size_t idx); + + LogVarSet getLogVarSetExcluding (size_t idx) const; + vector literals_; - ConstraintTree* ct_; + LogVarSet ipgLogVars_; + ConstraintTree constr_; }; From fbc44ba17d4c350b5aeedb28345b61ebb840b8c3 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Mon, 29 Oct 2012 13:49:11 +0000 Subject: [PATCH 06/52] improments in exportToGraphViz --- packages/CLPBN/horus/LiftedCircuit.cpp | 36 ++++++++++++-------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index 8b6214428..93566e8df 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -511,10 +511,12 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) { assert (node != 0); - static unsigned nrOrNodes = 0; - static unsigned nrAndNodes = 0; - static unsigned nrSetOrNodes = 0; - static unsigned nrSetAndNodes = 0; + static unsigned nrAuxNodes = 0; + stringstream ss; + ss << "n" << nrAuxNodes; + string auxNode = ss.str(); + nrAuxNodes ++; + switch (getCircuitNodeType (node)) { @@ -530,14 +532,13 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) os << "\"]" ; os << endl; } - os << "or" << nrOrNodes << " [label=\"∨\"]" << endl; - os << '"' << node << '"' << " -> " << "or" << nrOrNodes; + os << auxNode << " [label=\"∨\"]" << endl; + os << escapeNode (node) << " -> " << auxNode; os << " [label=\"" << node->explanation() << "\"]" << endl; - os << "or" << nrOrNodes << " -> " ; + os << auxNode << " -> " ; os << escapeNode (*casted->leftBranch()) << endl; - os << "or" << nrOrNodes << " -> " ; + os << auxNode << " -> " ; os << escapeNode (*casted->rightBranch()) << endl; - nrOrNodes ++; exportToGraphViz (*casted->leftBranch(), os); exportToGraphViz (*casted->rightBranch(), os); break; @@ -553,21 +554,19 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) } os << "\"]" ; os << endl; - os << "and" << nrAndNodes << " [label=\"∧\"]" << endl; - os << '"' << node << '"' << " -> " << "and" << nrAndNodes; + os << auxNode << " [label=\"∧\"]" << endl; + os << escapeNode (node) << " -> " << auxNode; os << " [label=\"" << node->explanation() << "\"]" << endl; - os << "and" << nrAndNodes << " -> " ; + os << auxNode << " -> " ; os << escapeNode (*casted->leftBranch()) << endl; - os << "and" << nrAndNodes << " -> " ; + os << auxNode << " -> " ; os << escapeNode (*casted->rightBranch()) << endl; - nrAndNodes ++; exportToGraphViz (*casted->leftBranch(), os); exportToGraphViz (*casted->rightBranch(), os); break; } case SET_OR_NODE: { - nrSetOrNodes ++; assert (false); // not yet implemented } @@ -581,12 +580,11 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) } os << "\"]" ; os << endl; - os << "setand" << nrSetAndNodes << " [label=\"∧(X)\"]" << endl; - os << '"' << node << '"' << " -> " << "setand" << nrSetAndNodes; + os << auxNode << " [label=\"∧(X)\"]" << endl; + os << escapeNode (node) << " -> " << auxNode; os << " [label=\"" << node->explanation() << "\"]" << endl; - os << "setand" << nrSetAndNodes << " -> " ; + os << auxNode << " -> " ; os << escapeNode (*casted->follow()) << endl; - nrSetAndNodes ++; exportToGraphViz (*casted->follow(), os); break; } From c2b1434969c8708118f9dd061e42fbfc595f7132 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Mon, 29 Oct 2012 15:39:56 +0000 Subject: [PATCH 07/52] show weights in dot file and add support for smoothing set-and nodes --- packages/CLPBN/horus/LiftedCircuit.cpp | 111 ++++++++++++++++--------- packages/CLPBN/horus/LiftedCircuit.h | 6 +- 2 files changed, 76 insertions(+), 41 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index 93566e8df..e3e9f1443 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -8,6 +8,7 @@ OrNode::weight (void) const { double lw = leftBranch_->weight(); double rw = rightBranch_->weight(); + cout << ">>>> OR NODE res = " << lw << " + " << rw << endl; return Globals::logDomain ? Util::logSum (lw, rw) : lw + rw; } @@ -38,9 +39,10 @@ double SetAndNode::weight (void) const { unsigned nrGroundings = 2; // FIXME + double w = follow_->weight(); return Globals::logDomain - ? follow_->weight() * nrGroundings - : std::pow (follow_->weight(), nrGroundings); + ? w * nrGroundings + : std::pow (w, nrGroundings); } @@ -52,14 +54,14 @@ LeafNode::weight (void) const assert (clauses()[0].isUnit()); Clause c = clauses()[0]; double weight = c.literals()[0].weight(); - unsigned nrGroundings = c.constr().size(); + LogVarSet lvs = c.constr().logVarSet() - c.ipgLogVars(); + unsigned nrGroundings = 1; + if (lvs.empty() == false) { + ConstraintTree ct = c.constr(); + ct.project (lvs); + nrGroundings = ct.size(); + } assert (nrGroundings != 0); - double www = Globals::logDomain - ? weight * nrGroundings - : std::pow (weight, nrGroundings); - - cout << "leaf weight(" << clauses()[0].literals()[0] << "): " << www << endl; - return Globals::logDomain ? weight * nrGroundings : std::pow (weight, nrGroundings); @@ -325,29 +327,33 @@ LiftedCircuit::tryIndepPartialGrounding ( Clauses& clauses) { // assumes that all literals have logical variables - LogVar X = clauses[0].constr().logVars()[0]; - ConstraintTree ct = clauses[0].constr(); + // else, shannon decomp was possible - // FIXME this is so weak ... - ct.project ({X}); - for (size_t i = 0; i < clauses.size(); i++) { - if (clauses[i].constr().logVars().size() == 1) { - if (ct.tupleSet() != clauses[i].constr().tupleSet()) { + LogVarSet lvs = clauses[0].constr().logVarSet(); + lvs -= clauses[0].ipgLogVars(); + for (unsigned i = 0; i < lvs.size(); i++) { + LogVar X = lvs[i]; + ConstraintTree ct = clauses[0].constr(); + ct.project ({X}); + for (size_t j = 0; j < clauses.size(); j++) { + if (clauses[j].constr().logVars().size() == 1) { + if (ct.tupleSet() != clauses[j].constr().tupleSet()) { + return false; + } + } else { return false; } - } else { - return false; } } - + // FIXME this is so broken ... Clauses newClauses = clauses; for (size_t i = 0; i < clauses.size(); i++) { newClauses[i].addIpgLogVar (clauses[i].constr().logVars()[0]); } - string explanation = " IPG" ; - SetAndNode* node = new SetAndNode (clauses, explanation); + // FIXME + SetAndNode* node = new SetAndNode (2, clauses); *follow = node; compile (node->follow(), newClauses); return true; @@ -357,8 +363,8 @@ LiftedCircuit::tryIndepPartialGrounding ( bool LiftedCircuit::tryGrounding ( - CircuitNode** follow, - Clauses& clauses) + CircuitNode**, + Clauses&) { return false; /* @@ -440,15 +446,18 @@ LiftedCircuit::smoothCircuit (CircuitNode* node) } case CircuitNodeType::SET_OR_NODE: { - // TODO + break; } case CircuitNodeType::SET_AND_NODE: { - // TODO + SetAndNode* casted = dynamic_cast(node); + propagatingLids = smoothCircuit (*casted->follow()); + break; } case CircuitNodeType::INC_EXC_NODE: { // TODO + break; } case CircuitNodeType::LEAF_NODE: { @@ -524,21 +533,30 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) OrNode* casted = dynamic_cast(node); const Clauses& clauses = node->clauses(); if (clauses.empty() == false) { - os << escapeNode (node) << " [shape=box,label=\"" ; - for (size_t i = 0; i < clauses.size(); i++) { - if (i != 0) os << "\\n" ; - os << clauses[i]; - } - os << "\"]" ; - os << endl; + os << escapeNode (node) << " [shape=box,label=\"" ; + for (size_t i = 0; i < clauses.size(); i++) { + if (i != 0) os << "\\n" ; + os << clauses[i]; + } + os << "\"]" ; + os << endl; } + os << auxNode << " [label=\"∨\"]" << endl; os << escapeNode (node) << " -> " << auxNode; - os << " [label=\"" << node->explanation() << "\"]" << endl; + os << " [label=\"" << node->explanation() << "\"]" ; + os << endl; + os << auxNode << " -> " ; - os << escapeNode (*casted->leftBranch()) << endl; + os << escapeNode (*casted->leftBranch()); + os << " [label=\" " << (*casted->leftBranch())->weight() << "\"]" ; + os << endl; + os << auxNode << " -> " ; - os << escapeNode (*casted->rightBranch()) << endl; + os << escapeNode (*casted->rightBranch()); + os << " [label=\" " << (*casted->rightBranch())->weight() << "\"]" ; + os << endl; + exportToGraphViz (*casted->leftBranch(), os); exportToGraphViz (*casted->rightBranch(), os); break; @@ -554,13 +572,22 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) } os << "\"]" ; os << endl; + os << auxNode << " [label=\"∧\"]" << endl; os << escapeNode (node) << " -> " << auxNode; - os << " [label=\"" << node->explanation() << "\"]" << endl; + os << " [label=\"" << node->explanation() << "\"]" ; + os << endl; + os << auxNode << " -> " ; - os << escapeNode (*casted->leftBranch()) << endl; + 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; @@ -580,11 +607,17 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) } os << "\"]" ; os << endl; + os << auxNode << " [label=\"∧(X)\"]" << endl; os << escapeNode (node) << " -> " << auxNode; - os << " [label=\"" << node->explanation() << "\"]" << endl; + os << " [label=\"" << node->explanation() << "\"]" ; + os << endl; + os << auxNode << " -> " ; - os << escapeNode (*casted->follow()) << endl; + os << escapeNode (*casted->follow()); + os << " [label=\" " << (*casted->follow())->weight() << "\"]" ; + os << endl; + exportToGraphViz (*casted->follow(), os); break; } diff --git a/packages/CLPBN/horus/LiftedCircuit.h b/packages/CLPBN/horus/LiftedCircuit.h index 435a26517..7006d2f82 100644 --- a/packages/CLPBN/horus/LiftedCircuit.h +++ b/packages/CLPBN/horus/LiftedCircuit.h @@ -108,13 +108,15 @@ class SetOrNode : public CircuitNode class SetAndNode : public CircuitNode { public: - SetAndNode (const Clauses& clauses, string explanation = "") - : CircuitNode (clauses, explanation), follow_(0) { } + SetAndNode (unsigned nrGroundings, const Clauses& clauses) + : CircuitNode (clauses, ""), nrGroundings_(nrGroundings), + follow_(0) { } double weight (void) const; CircuitNode** follow (void) { return &follow_; } private: + unsigned nrGroundings_; CircuitNode* follow_; }; From 324ea1a96c71b9bd51733a7403133b54bd01ea17 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Mon, 29 Oct 2012 20:49:21 +0000 Subject: [PATCH 08/52] make independent partial ground suck less --- packages/CLPBN/horus/LiftedCircuit.cpp | 69 ++++++++++++++++---------- packages/CLPBN/horus/LiftedCircuit.h | 8 +-- packages/CLPBN/horus/LiftedWCNF.cpp | 23 +++++++++ packages/CLPBN/horus/LiftedWCNF.h | 2 + 4 files changed, 73 insertions(+), 29 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index e3e9f1443..0b1ebcdf1 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -329,33 +329,50 @@ LiftedCircuit::tryIndepPartialGrounding ( // assumes that all literals have logical variables // else, shannon decomp was possible - LogVarSet lvs = clauses[0].constr().logVarSet(); - lvs -= clauses[0].ipgLogVars(); - for (unsigned i = 0; i < lvs.size(); i++) { - LogVar X = lvs[i]; + vector lvIndices; + LogVarSet lvs = clauses[0].ipgCandidates(); + for (size_t i = 0; i < lvs.size(); i++) { + lvIndices.clear(); + lvIndices.push_back (i); ConstraintTree ct = clauses[0].constr(); - ct.project ({X}); - for (size_t j = 0; j < clauses.size(); j++) { - if (clauses[j].constr().logVars().size() == 1) { - if (ct.tupleSet() != clauses[j].constr().tupleSet()) { - return false; - } - } else { - return false; + ct.project ({lvs[i]}); + if (tryIndepPartialGroundingAux (clauses, ct, lvIndices)) { + Clauses newClauses = clauses; + for (size_t i = 0; i < clauses.size(); i++) { + LogVar lv = clauses[i].ipgCandidates()[lvIndices[i]]; + newClauses[i].addIpgLogVar (lv); } + SetAndNode* node = new SetAndNode (ct.size(), clauses); + *follow = node; + compile (node->follow(), newClauses); + return true; } } - - // FIXME this is so broken ... - Clauses newClauses = clauses; - for (size_t i = 0; i < clauses.size(); i++) { - newClauses[i].addIpgLogVar (clauses[i].constr().logVars()[0]); + return false; +} + + + +bool +LiftedCircuit::tryIndepPartialGroundingAux ( + Clauses& clauses, + ConstraintTree& ct, + vector& lvIndices) +{ + for (size_t j = 1; j < clauses.size(); j++) { + LogVarSet lvs2 = clauses[j].ipgCandidates(); + for (size_t k = 0; k < lvs2.size(); k++) { + ConstraintTree ct2 = clauses[j].constr(); + ct2.project ({lvs2[k]}); + if (ct.tupleSet() == ct2.tupleSet()) { + lvIndices.push_back (k); + break; + } + } + if (lvIndices.size() != j+1) { + return false; + } } - - // FIXME - SetAndNode* node = new SetAndNode (2, clauses); - *follow = node; - compile (node->follow(), newClauses); return true; } @@ -414,8 +431,8 @@ LiftedCircuit::smoothCircuit (CircuitNode* node) } SmoothNode* smoothNode = new SmoothNode (clauses); CircuitNode** prev = casted->leftBranch(); - string explanation = " smoothing" ; - AndNode* andNode = new AndNode ((*prev)->clauses(), smoothNode, *prev, explanation); + AndNode* andNode = new AndNode ((*prev)->clauses(), + smoothNode, *prev, " smoothing"); *prev = andNode; } if (missingRight.empty() == false) { @@ -427,8 +444,8 @@ LiftedCircuit::smoothCircuit (CircuitNode* node) } SmoothNode* smoothNode = new SmoothNode (clauses); CircuitNode** prev = casted->rightBranch(); - string explanation = " smoothing" ; - AndNode* andNode = new AndNode ((*prev)->clauses(), smoothNode, *prev, explanation); + AndNode* andNode = new AndNode ((*prev)->clauses(), smoothNode, + *prev, " smoothing"); *prev = andNode; } propagatingLids |= lids1; diff --git a/packages/CLPBN/horus/LiftedCircuit.h b/packages/CLPBN/horus/LiftedCircuit.h index 7006d2f82..0db93679c 100644 --- a/packages/CLPBN/horus/LiftedCircuit.h +++ b/packages/CLPBN/horus/LiftedCircuit.h @@ -109,15 +109,15 @@ class SetAndNode : public CircuitNode { public: SetAndNode (unsigned nrGroundings, const Clauses& clauses) - : CircuitNode (clauses, ""), nrGroundings_(nrGroundings), + : CircuitNode (clauses, "IPG"), nrGroundings_(nrGroundings), follow_(0) { } double weight (void) const; CircuitNode** follow (void) { return &follow_; } private: - unsigned nrGroundings_; - CircuitNode* follow_; + unsigned nrGroundings_; + CircuitNode* follow_; }; @@ -191,6 +191,8 @@ class LiftedCircuit bool tryIndependence (CircuitNode** follow, Clauses& clauses); bool tryShannonDecomp (CircuitNode** follow, Clauses& clauses); bool tryIndepPartialGrounding (CircuitNode** follow, Clauses& clauses); + bool tryIndepPartialGroundingAux (Clauses& clauses, ConstraintTree& ct, + vector& indices); bool tryGrounding (CircuitNode** follow, Clauses& clauses); TinySet smoothCircuit (CircuitNode* node); diff --git a/packages/CLPBN/horus/LiftedWCNF.cpp b/packages/CLPBN/horus/LiftedWCNF.cpp index 4ad651621..657016988 100644 --- a/packages/CLPBN/horus/LiftedWCNF.cpp +++ b/packages/CLPBN/horus/LiftedWCNF.cpp @@ -136,6 +136,29 @@ Clause::removeNegativeLiterals (LiteralId lid) +LogVarSet +Clause::ipgCandidates (void) const +{ + LogVarSet candidates; + LogVarSet allLvs = constr_.logVarSet(); + allLvs -= ipgLogVars_; + 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; +} + + + TinySet Clause::lidSet (void) const { diff --git a/packages/CLPBN/horus/LiftedWCNF.h b/packages/CLPBN/horus/LiftedWCNF.h index 155ec48e8..564ec0fd4 100644 --- a/packages/CLPBN/horus/LiftedWCNF.h +++ b/packages/CLPBN/horus/LiftedWCNF.h @@ -90,6 +90,8 @@ class Clause void addIpgLogVar (LogVar X) { ipgLogVars_.insert (X); } + LogVarSet ipgCandidates (void) const; + TinySet lidSet (void) const; friend std::ostream& operator<< (ostream &os, const Clause& clause); From d07ea730504abae9592bd33151ac13626472b18c Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Mon, 29 Oct 2012 21:37:58 +0000 Subject: [PATCH 09/52] add projectedCopy --- packages/CLPBN/horus/ConstraintTree.cpp | 10 ++++++++++ packages/CLPBN/horus/ConstraintTree.h | 2 ++ 2 files changed, 12 insertions(+) diff --git a/packages/CLPBN/horus/ConstraintTree.cpp b/packages/CLPBN/horus/ConstraintTree.cpp index 9702e4a4a..07aaf35a3 100644 --- a/packages/CLPBN/horus/ConstraintTree.cpp +++ b/packages/CLPBN/horus/ConstraintTree.cpp @@ -367,6 +367,16 @@ ConstraintTree::project (const LogVarSet& X) +ConstraintTree +ConstraintTree::projectedCopy (const LogVarSet& X) +{ + ConstraintTree copy = *this; + copy.project (X); + return copy; +} + + + void ConstraintTree::remove (const LogVarSet& X) { diff --git a/packages/CLPBN/horus/ConstraintTree.h b/packages/CLPBN/horus/ConstraintTree.h index 0cc01c841..d233a2e97 100644 --- a/packages/CLPBN/horus/ConstraintTree.h +++ b/packages/CLPBN/horus/ConstraintTree.h @@ -157,6 +157,8 @@ class ConstraintTree void applySubstitution (const Substitution&); void project (const LogVarSet&); + + ConstraintTree projectedCopy (const LogVarSet&); void remove (const LogVarSet&); From b6df8a66b19dbca758b09e0d0ff3c196e2982273 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Tue, 30 Oct 2012 00:15:40 +0000 Subject: [PATCH 10/52] add assignement operator to ConstraintTree --- packages/CLPBN/horus/ConstraintTree.cpp | 17 ++++++++++++++--- packages/CLPBN/horus/ConstraintTree.h | 2 ++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/CLPBN/horus/ConstraintTree.cpp b/packages/CLPBN/horus/ConstraintTree.cpp index 07aaf35a3..59705e1e1 100644 --- a/packages/CLPBN/horus/ConstraintTree.cpp +++ b/packages/CLPBN/horus/ConstraintTree.cpp @@ -187,9 +187,7 @@ ConstraintTree::ConstraintTree ( ConstraintTree::ConstraintTree (const ConstraintTree& ct) { - root_ = CTNode::copySubtree (ct.root_); - logVars_ = ct.logVars_; - logVarSet_ = ct.logVarSet_; + *this = ct; } @@ -875,6 +873,19 @@ ConstraintTree::copyLogVar (LogVar X_1, LogVar 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 { diff --git a/packages/CLPBN/horus/ConstraintTree.h b/packages/CLPBN/horus/ConstraintTree.h index d233a2e97..071a96a5e 100644 --- a/packages/CLPBN/horus/ConstraintTree.h +++ b/packages/CLPBN/horus/ConstraintTree.h @@ -199,6 +199,8 @@ class ConstraintTree ConstraintTrees ground (LogVar); void copyLogVar (LogVar,LogVar); + + ConstraintTree& operator= (const ConstraintTree& ct); private: unsigned countTuples (const CTNode*) const; From 8b77b93a3b0e3cfaec6b8502f767528cde7274ea Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Tue, 30 Oct 2012 00:21:10 +0000 Subject: [PATCH 11/52] add support for inclusion-exclusion --- packages/CLPBN/horus/LiftedCircuit.cpp | 112 +++++++++++++++++++++++-- packages/CLPBN/horus/LiftedCircuit.h | 20 +++-- packages/CLPBN/horus/LiftedWCNF.cpp | 2 +- packages/CLPBN/horus/LiftedWCNF.h | 7 +- 4 files changed, 123 insertions(+), 18 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index 0b1ebcdf1..9586c7bbb 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -8,7 +8,6 @@ OrNode::weight (void) const { double lw = leftBranch_->weight(); double rw = rightBranch_->weight(); - cout << ">>>> OR NODE res = " << lw << " + " << rw << endl; return Globals::logDomain ? Util::logSum (lw, rw) : lw + rw; } @@ -28,7 +27,6 @@ double SetOrNode::weight (void) const { // TODO - assert (false); return 0.0; } @@ -38,11 +36,10 @@ SetOrNode::weight (void) const double SetAndNode::weight (void) const { - unsigned nrGroundings = 2; // FIXME double w = follow_->weight(); return Globals::logDomain - ? w * nrGroundings - : std::pow (w, nrGroundings); + ? w * nrGroundings_ + : std::pow (w, nrGroundings_); } @@ -108,7 +105,9 @@ LiftedCircuit::LiftedCircuit (const LiftedWCNF* lwcnf) //ccc.push_back (c2); //compile (&root_, lwcnf->clauses()); - compile (&root_, ccc); + Clauses cccc = {ccc[6],ccc[4]}; + cccc.front().removeLiteral (2); + compile (&root_, cccc); exportToGraphViz("circuit.dot"); smoothCircuit(); exportToGraphViz("smooth.dot"); @@ -189,6 +188,10 @@ LiftedCircuit::compile ( return; } + if (tryInclusionExclusion (follow, clauses)) { + return; + } + if (tryIndepPartialGrounding (follow, clauses)) { return; } @@ -309,9 +312,9 @@ LiftedCircuit::tryShannonDecomp ( stringstream explanation; explanation << " SD on " << literals[j]; OrNode* orNode = new OrNode (clauses, explanation.str()); - (*follow) = orNode; compile (orNode->leftBranch(), leftClauses); compile (orNode->rightBranch(), rightClauses); + (*follow) = orNode; return true; } } @@ -321,6 +324,56 @@ LiftedCircuit::tryShannonDecomp ( +bool +LiftedCircuit::tryInclusionExclusion ( + CircuitNode** follow, + Clauses& 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++) { + bool indep = true; + for (size_t k = 0; k < literals.size(); k++) { + LogVarSet intersect = literals[j].logVarSet() + & literals[k].logVarSet(); + if (j != k && intersect.empty() == false) { + indep = false; + break; + } + } + if (indep) { + // TODO i am almost sure that this will + // have to be count normalized too! + ConstraintTree really = clauses[i].constr(); + Clause c1 (really.projectedCopy ( + literals[j].logVars())); + c1.addLiteral (literals[j]); + Clause c2 = clauses[i]; + c2.removeLiteral (j); + Clauses plus1Clauses = clauses; + Clauses plus2Clauses = clauses; + Clauses minusClauses = clauses; + plus1Clauses.erase (plus1Clauses.begin() + i); + plus2Clauses.erase (plus2Clauses.begin() + i); + minusClauses.erase (minusClauses.begin() + i); + plus1Clauses.push_back (c1); + plus2Clauses.push_back (c2); + minusClauses.push_back (c1); + minusClauses.push_back (c2); + IncExcNode* ieNode = new IncExcNode (clauses); + compile (ieNode->plus1Branch(), plus1Clauses); + compile (ieNode->plus2Branch(), plus2Clauses); + compile (ieNode->minusBranch(), minusClauses); + *follow = ieNode; + return true; + } + } + } + return false; +} + + + bool LiftedCircuit::tryIndepPartialGrounding ( CircuitNode** follow, @@ -328,7 +381,6 @@ LiftedCircuit::tryIndepPartialGrounding ( { // assumes that all literals have logical variables // else, shannon decomp was possible - vector lvIndices; LogVarSet lvs = clauses[0].ipgCandidates(); for (size_t i = 0; i < lvs.size(); i++) { @@ -503,9 +555,13 @@ LiftedCircuit::getCircuitNodeType (const CircuitNode* node) const } else if (dynamic_cast(node) != 0) { type = CircuitNodeType::AND_NODE; } else if (dynamic_cast(node) != 0) { + // TODO + assert (false); 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) { @@ -611,7 +667,8 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) } case SET_OR_NODE: { - assert (false); // not yet implemented + // TODO + assert (false); } case SET_AND_NODE: { @@ -639,6 +696,43 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) break; } + case INC_EXC_NODE: { + IncExcNode* casted = dynamic_cast(node); + const Clauses& clauses = node->clauses(); + os << escapeNode (node) << " [shape=box,label=\"" ; + for (size_t i = 0; i < clauses.size(); i++) { + if (i != 0) os << "\\n" ; + os << clauses[i]; + } + os << "\"]" ; + os << endl; + + os << auxNode << " [label=\"IncExc\"]" << endl; + os << escapeNode (node) << " -> " << auxNode; + os << " [label=\"" << node->explanation() << "\"]" ; + os << endl; + + os << auxNode << " -> " ; + os << escapeNode (*casted->plus1Branch()); + os << " [label=\" " << (*casted->plus1Branch())->weight() << "\"]" ; + os << endl; + + os << auxNode << " -> " ; + os << escapeNode (*casted->plus2Branch()); + os << " [label=\" " << (*casted->plus2Branch())->weight() << "\"]" ; + os << endl; + + os << auxNode << " -> " ; + os << escapeNode (*casted->minusBranch()) << endl; + os << " [label=\" " << (*casted->minusBranch())->weight() << "\"]" ; + os << endl; + + exportToGraphViz (*casted->plus1Branch(), os); + exportToGraphViz (*casted->plus2Branch(), os); + exportToGraphViz (*casted->minusBranch(), os); + break; + } + case LEAF_NODE: { os << escapeNode (node); os << " [shape=box,label=\"" ; diff --git a/packages/CLPBN/horus/LiftedCircuit.h b/packages/CLPBN/horus/LiftedCircuit.h index 0db93679c..98ce61086 100644 --- a/packages/CLPBN/horus/LiftedCircuit.h +++ b/packages/CLPBN/horus/LiftedCircuit.h @@ -109,7 +109,7 @@ class SetAndNode : public CircuitNode { public: SetAndNode (unsigned nrGroundings, const Clauses& clauses) - : CircuitNode (clauses, "IPG"), nrGroundings_(nrGroundings), + : CircuitNode (clauses, " IPG"), nrGroundings_(nrGroundings), follow_(0) { } double weight (void) const; @@ -122,13 +122,20 @@ class SetAndNode : public CircuitNode -class IncExclNode : public CircuitNode +class IncExcNode : public CircuitNode { public: + IncExcNode (const Clauses& clauses) + : CircuitNode (clauses), plus1Branch_(0), + plus2Branch_(0), minusBranch_(0) { } + + CircuitNode** plus1Branch (void) { return &plus1Branch_; } + CircuitNode** plus2Branch (void) { return &plus2Branch_; } + CircuitNode** minusBranch (void) { return &minusBranch_; } private: - CircuitNode* xFollow_; - CircuitNode* yFollow_; - CircuitNode* zFollow_; + CircuitNode* plus1Branch_; + CircuitNode* plus2Branch_; + CircuitNode* minusBranch_; }; @@ -156,7 +163,7 @@ class SmoothNode : public CircuitNode class TrueNode : public CircuitNode { public: - TrueNode () : CircuitNode ({}) { } + TrueNode (void) : CircuitNode ({}) { } double weight (void) const; }; @@ -190,6 +197,7 @@ class LiftedCircuit 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, vector& indices); diff --git a/packages/CLPBN/horus/LiftedWCNF.cpp b/packages/CLPBN/horus/LiftedWCNF.cpp index 657016988..d69f4bd01 100644 --- a/packages/CLPBN/horus/LiftedWCNF.cpp +++ b/packages/CLPBN/horus/LiftedWCNF.cpp @@ -203,7 +203,7 @@ std::ostream& operator<< (ostream &os, const Clause& clause) os << clause.literals_[i].toString (clause.ipgLogVars_); } if (clause.constr_.empty() == false) { - ConstraintTree copy = clause.constr_; + ConstraintTree copy (clause.constr_); copy.moveToTop (copy.logVarSet().elements()); os << " | " << copy.tupleSet(); } diff --git a/packages/CLPBN/horus/LiftedWCNF.h b/packages/CLPBN/horus/LiftedWCNF.h index 564ec0fd4..89ebec029 100644 --- a/packages/CLPBN/horus/LiftedWCNF.h +++ b/packages/CLPBN/horus/LiftedWCNF.h @@ -25,8 +25,10 @@ class Literal LiteralId lid (void) const { return lid_; } LogVars logVars (void) const { return logVars_; } + + LogVarSet logVarSet (void) const { return LogVarSet (logVars_); } - // FIXME not log aware :( + // FIXME this is not log aware :( double weight (void) const { return weight_ < 0.0 ? 1.0 : weight_; } void negate (void) { negated_ = !negated_; } @@ -96,8 +98,9 @@ class Clause friend std::ostream& operator<< (ostream &os, const Clause& clause); - private: void removeLiteral (size_t idx); + + private: LogVarSet getLogVarSetExcluding (size_t idx) const; From 864f7643910bbd6a26018fffc6405e6351e9fd3f Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Tue, 30 Oct 2012 01:51:10 +0000 Subject: [PATCH 12/52] support model counting in inc-exc nodes --- packages/CLPBN/horus/LiftedCircuit.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index 9586c7bbb..f185c5212 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -44,6 +44,22 @@ SetAndNode::weight (void) const +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; +} + + + double LeafNode::weight (void) const { From a75799b34f88d1b2218f2a14f1ec4bdb6324b28e Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Tue, 30 Oct 2012 12:41:00 +0000 Subject: [PATCH 13/52] small improvements --- packages/CLPBN/horus/LiftedCircuit.cpp | 28 +++++++++++++++----------- packages/CLPBN/horus/LiftedCircuit.h | 12 +++++++---- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index f185c5212..eb8d4fe33 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -110,6 +110,17 @@ TrueNode::weight (void) const +double +CompilationFailedNode::weight (void) const +{ + // we should not perform model counting + // in compilation failed nodes + abort(); + return 0.0; +} + + + LiftedCircuit::LiftedCircuit (const LiftedWCNF* lwcnf) : lwcnf_(lwcnf) { @@ -217,7 +228,7 @@ LiftedCircuit::compile ( } // assert (false); - *follow = new FailNode (clauses); + *follow = new CompilationFailedNode (clauses); } @@ -237,14 +248,10 @@ LiftedCircuit::tryUnitPropagation ( if (clauses[i].literals()[0].isPositive()) { if (clauses[j].containsPositiveLiteral (lid) == false) { Clause newClause = clauses[j]; - //cout << "new j : " << clauses[j] << endl; - //cout << "new clause: " << newClause << endl; - //cout << "clvs: " << clauses[j].constr()->logVars() << endl; newClause.removeNegativeLiterals (lid); newClauses.push_back (newClause); } } else if (clauses[i].literals()[0].isNegative()) { - //cout << "unit prop of = " << clauses[i].literals()[0] << endl; if (clauses[j].containsNegativeLiteral (lid) == false) { Clause newClause = clauses[j]; newClause.removePositiveLiterals (lid); @@ -254,7 +261,6 @@ LiftedCircuit::tryUnitPropagation ( } } stringstream explanation; - explanation << " UP of " << clauses[i]; AndNode* andNode = new AndNode (clauses, explanation.str()); Clauses leftClauses = {clauses[i]}; compile (andNode->leftBranch(), leftClauses); @@ -551,7 +557,7 @@ LiftedCircuit::smoothCircuit (CircuitNode* node) // case CircuitNodeType::SMOOTH_NODE: // case CircuitNodeType::TRUE_NODE: - // case CircuitNodeType::FAIL_NODE: + // case CircuitNodeType::COMPILATION_FAILED_NODE: default: break; @@ -571,8 +577,6 @@ LiftedCircuit::getCircuitNodeType (const CircuitNode* node) const } else if (dynamic_cast(node) != 0) { type = CircuitNodeType::AND_NODE; } else if (dynamic_cast(node) != 0) { - // TODO - assert (false); type = CircuitNodeType::SET_OR_NODE; } else if (dynamic_cast(node) != 0) { type = CircuitNodeType::SET_AND_NODE; @@ -584,8 +588,8 @@ LiftedCircuit::getCircuitNodeType (const CircuitNode* node) const type = CircuitNodeType::SMOOTH_NODE; } else if (dynamic_cast(node) != 0) { type = CircuitNodeType::TRUE_NODE; - } else if (dynamic_cast(node) != 0) { - type = CircuitNodeType::FAIL_NODE; + } else if (dynamic_cast(node) != 0) { + type = CircuitNodeType::COMPILATION_FAILED_NODE; } else { assert (false); } @@ -778,7 +782,7 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) break; } - case FAIL_NODE: { + case COMPILATION_FAILED_NODE: { os << escapeNode (node); os << " [shape=box,style=filled,fillcolor=brown1,label=\"" ; const Clauses& clauses = node->clauses(); diff --git a/packages/CLPBN/horus/LiftedCircuit.h b/packages/CLPBN/horus/LiftedCircuit.h index 98ce61086..35bd794ec 100644 --- a/packages/CLPBN/horus/LiftedCircuit.h +++ b/packages/CLPBN/horus/LiftedCircuit.h @@ -13,7 +13,7 @@ enum CircuitNodeType { LEAF_NODE, SMOOTH_NODE, TRUE_NODE, - FAIL_NODE + COMPILATION_FAILED_NODE }; @@ -28,7 +28,7 @@ class CircuitNode Clauses clauses (void) { return clauses_; } - virtual double weight (void) const { return 0; } + virtual double weight (void) const = 0; string explanation (void) const { return explanation_; } @@ -128,6 +128,8 @@ class IncExcNode : public CircuitNode IncExcNode (const Clauses& clauses) : CircuitNode (clauses), plus1Branch_(0), plus2Branch_(0), minusBranch_(0) { } + + double weight (void) const; CircuitNode** plus1Branch (void) { return &plus1Branch_; } CircuitNode** plus2Branch (void) { return &plus2Branch_; } @@ -171,10 +173,12 @@ class TrueNode : public CircuitNode -class FailNode : public CircuitNode +class CompilationFailedNode : public CircuitNode { public: - FailNode (const Clauses& clauses) : CircuitNode (clauses) { } + CompilationFailedNode (const Clauses& clauses) : CircuitNode (clauses) { } + + double weight (void) const; }; From b31a047635b0da321bed48107ea3a430cfbbd2b2 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Tue, 30 Oct 2012 14:31:52 +0000 Subject: [PATCH 14/52] refactor exportToGraphViz --- packages/CLPBN/horus/LiftedCircuit.cpp | 95 +++++++++----------------- packages/CLPBN/horus/LiftedCircuit.h | 3 + 2 files changed, 37 insertions(+), 61 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index eb8d4fe33..843d7596f 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -261,6 +261,7 @@ LiftedCircuit::tryUnitPropagation ( } } stringstream explanation; + explanation << " UP on" << clauses[i].literals()[0]; AndNode* andNode = new AndNode (clauses, explanation.str()); Clauses leftClauses = {clauses[i]}; compile (andNode->leftBranch(), leftClauses); @@ -282,12 +283,13 @@ LiftedCircuit::tryIndependence ( if (clauses.size() == 1) { return false; } + // TODO this independence is a little weak for (size_t i = 0; i < clauses.size(); i++) { bool indep = true; TinySet lids1 = clauses[i].lidSet(); for (size_t j = 0; j < clauses.size(); j++) { TinySet lids2 = clauses[j].lidSet(); - if (((lids1 & lids2).empty() == false) && i != j) { + if (i != j && ((lids1 & lids2).empty() == false)) { indep = false; break; } @@ -296,7 +298,7 @@ LiftedCircuit::tryIndependence ( Clauses newClauses = clauses; newClauses.erase (newClauses.begin() + i); stringstream explanation; - explanation << " independence" ; + explanation << " Independence on clause Nº " << i ; AndNode* andNode = new AndNode (clauses, explanation.str()); Clauses indepClause = {clauses[i]}; compile (andNode->leftBranch(), indepClause); @@ -506,7 +508,7 @@ LiftedCircuit::smoothCircuit (CircuitNode* node) SmoothNode* smoothNode = new SmoothNode (clauses); CircuitNode** prev = casted->leftBranch(); AndNode* andNode = new AndNode ((*prev)->clauses(), - smoothNode, *prev, " smoothing"); + smoothNode, *prev, " Smoothing"); *prev = andNode; } if (missingRight.empty() == false) { @@ -519,7 +521,7 @@ LiftedCircuit::smoothCircuit (CircuitNode* node) SmoothNode* smoothNode = new SmoothNode (clauses); CircuitNode** prev = casted->rightBranch(); AndNode* andNode = new AndNode ((*prev)->clauses(), smoothNode, - *prev, " smoothing"); + *prev, " Smoothing"); *prev = andNode; } propagatingLids |= lids1; @@ -624,16 +626,7 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) case OR_NODE: { OrNode* casted = dynamic_cast(node); - const Clauses& clauses = node->clauses(); - if (clauses.empty() == false) { - os << escapeNode (node) << " [shape=box,label=\"" ; - for (size_t i = 0; i < clauses.size(); i++) { - if (i != 0) os << "\\n" ; - os << clauses[i]; - } - os << "\"]" ; - os << endl; - } + printClauses (casted, os); os << auxNode << " [label=\"∨\"]" << endl; os << escapeNode (node) << " -> " << auxNode; @@ -657,14 +650,7 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) case AND_NODE: { AndNode* casted = dynamic_cast(node); - const Clauses& clauses = node->clauses(); - os << escapeNode (node) << " [shape=box,label=\"" ; - for (size_t i = 0; i < clauses.size(); i++) { - if (i != 0) os << "\\n" ; - os << clauses[i]; - } - os << "\"]" ; - os << endl; + printClauses (casted, os); os << auxNode << " [label=\"∧\"]" << endl; os << escapeNode (node) << " -> " << auxNode; @@ -693,14 +679,7 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) case SET_AND_NODE: { SetAndNode* casted = dynamic_cast(node); - const Clauses& clauses = node->clauses(); - os << escapeNode (node) << " [shape=box,label=\"" ; - for (size_t i = 0; i < clauses.size(); i++) { - if (i != 0) os << "\\n" ; - os << clauses[i]; - } - os << "\"]" ; - os << endl; + printClauses (casted, os); os << auxNode << " [label=\"∧(X)\"]" << endl; os << escapeNode (node) << " -> " << auxNode; @@ -718,14 +697,7 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) case INC_EXC_NODE: { IncExcNode* casted = dynamic_cast(node); - const Clauses& clauses = node->clauses(); - os << escapeNode (node) << " [shape=box,label=\"" ; - for (size_t i = 0; i < clauses.size(); i++) { - if (i != 0) os << "\\n" ; - os << clauses[i]; - } - os << "\"]" ; - os << endl; + printClauses (casted, os); os << auxNode << " [label=\"IncExc\"]" << endl; os << escapeNode (node) << " -> " << auxNode; @@ -754,24 +726,12 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) } case LEAF_NODE: { - os << escapeNode (node); - os << " [shape=box,label=\"" ; - os << node->clauses()[0]; - os << "\"]" ; - os << endl; + printClauses (node, os); break; } case SMOOTH_NODE: { - os << escapeNode (node); - os << " [shape=box,style=filled,fillcolor=chartreuse,label=\"" ; - const Clauses& clauses = node->clauses(); - for (size_t i = 0; i < clauses.size(); i++) { - if (i != 0) os << "\\n" ; - os << clauses[i]; - } - os << "\"]" ; - os << endl; + printClauses (node, os, "style=filled,fillcolor=chartreuse,"); break; } @@ -783,15 +743,7 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) } case COMPILATION_FAILED_NODE: { - os << escapeNode (node); - os << " [shape=box,style=filled,fillcolor=brown1,label=\"" ; - const Clauses& clauses = node->clauses(); - for (size_t i = 0; i < clauses.size(); i++) { - if (i != 0) os << "\\n" ; - os << clauses[i]; - } - os << "\"]" ; - os << endl; + printClauses (node, os, "style=filled,fillcolor=brown1,"); break; } @@ -800,3 +752,24 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) } } + + +void +LiftedCircuit::printClauses ( + const CircuitNode* node, + ofstream& os, + string extraOptions) +{ + const Clauses& clauses = node->clauses(); + if (node->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; + } +} + diff --git a/packages/CLPBN/horus/LiftedCircuit.h b/packages/CLPBN/horus/LiftedCircuit.h index 35bd794ec..7b11cfd9d 100644 --- a/packages/CLPBN/horus/LiftedCircuit.h +++ b/packages/CLPBN/horus/LiftedCircuit.h @@ -214,6 +214,9 @@ class LiftedCircuit string escapeNode (const CircuitNode* node) const; void exportToGraphViz (CircuitNode* node, ofstream&); + + void printClauses (const CircuitNode* node, ofstream&, + string extraOptions = ""); CircuitNode* root_; const LiftedWCNF* lwcnf_; From 77ef7b87cd3936848efb34f9764b991c0a3f60df Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Tue, 30 Oct 2012 15:48:19 +0000 Subject: [PATCH 15/52] support smoothing in inclusion-exclusion nodes --- packages/CLPBN/horus/LiftedCircuit.cpp | 78 ++++++++++++++------------ packages/CLPBN/horus/LiftedCircuit.h | 9 ++- 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index 843d7596f..fe40bee48 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -498,32 +498,8 @@ LiftedCircuit::smoothCircuit (CircuitNode* node) TinySet lids2 = smoothCircuit (*casted->rightBranch()); TinySet missingLeft = lids2 - lids1; TinySet missingRight = lids1 - lids2; - if (missingLeft.empty() == false) { - Clauses clauses; - for (size_t i = 0; i < missingLeft.size(); i++) { - Clause c = lwcnf_->createClauseForLiteral (missingLeft[i]); - c.addAndNegateLiteral (c.literals()[0]); - clauses.push_back (c); - } - SmoothNode* smoothNode = new SmoothNode (clauses); - CircuitNode** prev = casted->leftBranch(); - AndNode* andNode = new AndNode ((*prev)->clauses(), - smoothNode, *prev, " Smoothing"); - *prev = andNode; - } - if (missingRight.empty() == false) { - Clauses clauses; - for (size_t i = 0; i < missingRight.size(); i++) { - Clause c = lwcnf_->createClauseForLiteral (missingRight[i]); - c.addAndNegateLiteral (c.literals()[0]); - clauses.push_back (c); - } - SmoothNode* smoothNode = new SmoothNode (clauses); - CircuitNode** prev = casted->rightBranch(); - AndNode* andNode = new AndNode ((*prev)->clauses(), smoothNode, - *prev, " Smoothing"); - *prev = andNode; - } + createSmoothNode (missingLeft, casted->leftBranch()); + createSmoothNode (missingRight, casted->rightBranch()); propagatingLids |= lids1; propagatingLids |= lids2; break; @@ -549,7 +525,15 @@ LiftedCircuit::smoothCircuit (CircuitNode* node) } case CircuitNodeType::INC_EXC_NODE: { - // TODO + IncExcNode* casted = dynamic_cast(node); + TinySet lids1 = smoothCircuit (*casted->plus1Branch()); + TinySet lids2 = smoothCircuit (*casted->plus2Branch()); + TinySet missingPlus1 = lids2 - lids1; + TinySet missingPlus2 = lids1 - lids2; + createSmoothNode (missingPlus1, casted->plus1Branch()); + createSmoothNode (missingPlus2, casted->plus2Branch()); + propagatingLids |= lids1; + propagatingLids |= lids2; break; } @@ -570,6 +554,26 @@ LiftedCircuit::smoothCircuit (CircuitNode* node) +void +LiftedCircuit::createSmoothNode ( + const TinySet& missingLids, + CircuitNode** prev) +{ + if (missingLids.empty() == false) { + Clauses clauses; + for (size_t i = 0; i < missingLids.size(); i++) { + Clause c = lwcnf_->createClauseForLiteral (missingLids[i]); + c.addAndNegateLiteral (c.literals()[0]); + clauses.push_back (c); + } + SmoothNode* smoothNode = new SmoothNode (clauses); + *prev = new AndNode ((*prev)->clauses(), smoothNode, + *prev, " Smoothing"); + } +} + + + CircuitNodeType LiftedCircuit::getCircuitNodeType (const CircuitNode* node) const { @@ -600,16 +604,6 @@ LiftedCircuit::getCircuitNodeType (const CircuitNode* node) const -string -LiftedCircuit::escapeNode (const CircuitNode* node) const -{ - stringstream ss; - ss << "\"" << node << "\"" ; - return ss.str(); -} - - - void LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) { @@ -754,6 +748,16 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) +string +LiftedCircuit::escapeNode (const CircuitNode* node) const +{ + stringstream ss; + ss << "\"" << node << "\"" ; + return ss.str(); +} + + + void LiftedCircuit::printClauses ( const CircuitNode* node, diff --git a/packages/CLPBN/horus/LiftedCircuit.h b/packages/CLPBN/horus/LiftedCircuit.h index 7b11cfd9d..f7db3d334 100644 --- a/packages/CLPBN/horus/LiftedCircuit.h +++ b/packages/CLPBN/horus/LiftedCircuit.h @@ -209,14 +209,17 @@ class LiftedCircuit TinySet smoothCircuit (CircuitNode* node); - CircuitNodeType getCircuitNodeType (const CircuitNode* node) const; - - string escapeNode (const CircuitNode* node) const; + void createSmoothNode (const TinySet& lids, + CircuitNode** prev); + CircuitNodeType getCircuitNodeType (const CircuitNode* node) const; + void exportToGraphViz (CircuitNode* node, ofstream&); void printClauses (const CircuitNode* node, ofstream&, string extraOptions = ""); + + string escapeNode (const CircuitNode* node) const; CircuitNode* root_; const LiftedWCNF* lwcnf_; From e762d6be22e3b4e47cb9d26c23f90d0a224113b6 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Tue, 30 Oct 2012 16:00:20 +0000 Subject: [PATCH 16/52] tweak colors --- packages/CLPBN/horus/LiftedCircuit.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index fe40bee48..e31f13c79 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -515,6 +515,7 @@ LiftedCircuit::smoothCircuit (CircuitNode* node) } case CircuitNodeType::SET_OR_NODE: { + // TODO break; } @@ -540,11 +541,7 @@ LiftedCircuit::smoothCircuit (CircuitNode* node) case CircuitNodeType::LEAF_NODE: { propagatingLids.insert (node->clauses()[0].literals()[0].lid()); } - - // case CircuitNodeType::SMOOTH_NODE: - // case CircuitNodeType::TRUE_NODE: - // case CircuitNodeType::COMPILATION_FAILED_NODE: - + default: break; } @@ -720,12 +717,12 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) } case LEAF_NODE: { - printClauses (node, os); + printClauses (node, os, "style=filled,fillcolor=palegreen,"); break; } case SMOOTH_NODE: { - printClauses (node, os, "style=filled,fillcolor=chartreuse,"); + printClauses (node, os, "style=filled,fillcolor=lightblue,"); break; } @@ -737,7 +734,7 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) } case COMPILATION_FAILED_NODE: { - printClauses (node, os, "style=filled,fillcolor=brown1,"); + printClauses (node, os, "style=filled,fillcolor=salmon,"); break; } From 6877be897eaa2a6e864b1a547c56fc057f8dca86 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Wed, 31 Oct 2012 23:43:39 +0000 Subject: [PATCH 17/52] first stab for atom counting --- packages/CLPBN/horus/ConstraintTree.cpp | 24 +++ packages/CLPBN/horus/ConstraintTree.h | 2 + packages/CLPBN/horus/LiftedCircuit.cpp | 211 ++++++++++++++++++------ packages/CLPBN/horus/LiftedCircuit.h | 7 +- packages/CLPBN/horus/LiftedWCNF.cpp | 124 ++++++++++++-- packages/CLPBN/horus/LiftedWCNF.h | 40 ++++- 6 files changed, 336 insertions(+), 72 deletions(-) diff --git a/packages/CLPBN/horus/ConstraintTree.cpp b/packages/CLPBN/horus/ConstraintTree.cpp index 59705e1e1..bfabc982c 100644 --- a/packages/CLPBN/horus/ConstraintTree.cpp +++ b/packages/CLPBN/horus/ConstraintTree.cpp @@ -112,6 +112,8 @@ CTNode::copySubtree (const CTNode* root1) 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(); @@ -185,6 +187,28 @@ ConstraintTree::ConstraintTree ( +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; diff --git a/packages/CLPBN/horus/ConstraintTree.h b/packages/CLPBN/horus/ConstraintTree.h index 071a96a5e..0b48c3650 100644 --- a/packages/CLPBN/horus/ConstraintTree.h +++ b/packages/CLPBN/horus/ConstraintTree.h @@ -108,6 +108,8 @@ class ConstraintTree ConstraintTree (const LogVars&); ConstraintTree (const LogVars&, const Tuples&); + + ConstraintTree (vector> names); ConstraintTree (const ConstraintTree&); diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index e31f13c79..baa058170 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -115,7 +115,7 @@ CompilationFailedNode::weight (void) const { // we should not perform model counting // in compilation failed nodes - abort(); + // abort(); return 0.0; } @@ -125,19 +125,11 @@ LiftedCircuit::LiftedCircuit (const LiftedWCNF* lwcnf) : lwcnf_(lwcnf) { root_ = 0; - Clauses ccc = lwcnf->clauses(); - //ccc.erase (ccc.begin() + 5, ccc.end()); - //Clause c2 = ccc.front(); - //c2.removeLiteralByIndex (1); - //ccc.push_back (c2); - - //compile (&root_, lwcnf->clauses()); - Clauses cccc = {ccc[6],ccc[4]}; - cccc.front().removeLiteral (2); - compile (&root_, cccc); + Clauses clauses = lwcnf->clauses(); + compile (&root_, clauses); exportToGraphViz("circuit.dot"); smoothCircuit(); - exportToGraphViz("smooth.dot"); + exportToGraphViz("circuit.smooth.dot"); cout << "WEIGHTED MODEL COUNT = " << getWeightedModelCount() << endl; } @@ -188,18 +180,7 @@ LiftedCircuit::compile ( } if (clauses.size() == 1 && clauses[0].isUnit()) { - static int count = 0; count ++; *follow = new LeafNode (clauses[0]); - if (count == 1) { - // Clause c (new ConstraintTree({})); - // c.addLiteral (Literal (100,{})); - // *follow = new LeafNode (c); - } - if (count == 2) { - // Clause c (new ConstraintTree({})); - // c.addLiteral (Literal (101,{})); - // *follow = new LeafNode (c); - } return; } @@ -219,7 +200,11 @@ LiftedCircuit::compile ( return; } - if (tryIndepPartialGrounding (follow, clauses)) { + //if (tryIndepPartialGrounding (follow, clauses)) { + // return; + //} + + if (tryAtomCounting (follow, clauses)) { return; } @@ -229,7 +214,81 @@ LiftedCircuit::compile ( // assert (false); *follow = new CompilationFailedNode (clauses); +} + +void +LiftedCircuit::propagate ( + const Clause& c, + const Clause& unitClause, + Clauses& newClauses) +{ +/* + Literals literals = c.literals(); + for (size_t i = 0; i < literals.size(); i++) { + if (literals_[i].lid() == lid && literals[i].isPositive()) { + + return true; + } + } +*/ +} + + +bool +shatterCountedLogVars (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 (clauses[idx2]); + clauses[idx2].addPositiveCountedLogVar (lvs2[k]); + clauses.back().addNegativeCountedLogVar (lvs2[k]); + return true; + } + if (clauses[idx2].isCountedLogVar (lvs2[k]) + && clauses[idx1].isCountedLogVar (lvs1[k]) == false) { + clauses.push_back (clauses[idx1]); + clauses[idx1].addPositiveCountedLogVar (lvs1[k]); + clauses.back().addNegativeCountedLogVar (lvs1[k]); + return true; + } + } + } + } + } + return false; +} + + + +bool +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 = shatterCountedLogVars (clauses, i, j); + if (splitedSome) { + return true; + } + } + } + return false; +} + + + +void +shatterCountedLogVars (Clauses& clauses) +{ + while (shatterCountedLogVarsAux (clauses)) ; } @@ -239,22 +298,29 @@ LiftedCircuit::tryUnitPropagation ( CircuitNode** follow, Clauses& clauses) { + cout << "ALL CLAUSES:" << endl; + Clause::printClauses (clauses); + for (size_t i = 0; i < clauses.size(); i++) { if (clauses[i].isUnit()) { + cout << clauses[i] << " is unit!" << endl; Clauses newClauses; 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) == false) { + if (clauses[j].containsPositiveLiteral (lid, types) == false) { Clause newClause = clauses[j]; - newClause.removeNegativeLiterals (lid); + cout << "removing negative literals on " << newClause << endl; + newClause.removeNegativeLiterals (lid, types); newClauses.push_back (newClause); } } else if (clauses[i].literals()[0].isNegative()) { - if (clauses[j].containsNegativeLiteral (lid) == false) { + if (clauses[j].containsNegativeLiteral (lid, types) == false) { Clause newClause = clauses[j]; - newClause.removePositiveLiterals (lid); + cout << "removing negative literals on " << newClause << endl; + newClause.removePositiveLiterals (lid, types); newClauses.push_back (newClause); } } @@ -264,6 +330,7 @@ LiftedCircuit::tryUnitPropagation ( explanation << " UP on" << clauses[i].literals()[0]; AndNode* andNode = new AndNode (clauses, explanation.str()); Clauses leftClauses = {clauses[i]}; + cout << "new clauses: " << newClauses << endl; compile (andNode->leftBranch(), leftClauses); compile (andNode->rightBranch(), newClauses); (*follow) = andNode; @@ -454,6 +521,37 @@ LiftedCircuit::tryIndepPartialGroundingAux ( +bool +LiftedCircuit::tryAtomCounting ( + CircuitNode** follow, + Clauses& 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].logVars().size() == 1) { + // TODO check if not already in ipg and countedlvs + SetOrNode* setOrNode = new SetOrNode (clauses); + Clause c1 (clauses[i].constr().projectedCopy (literals[j].logVars())); + Clause c2 (clauses[i].constr().projectedCopy (literals[j].logVars())); + c1.addLiteral (literals[j]); + c2.addAndNegateLiteral (literals[j]); + c1.addPositiveCountedLogVar (literals[j].logVars().front()); + c2.addNegativeCountedLogVar (literals[j].logVars().front()); + clauses.push_back (c1); + clauses.push_back (c2); + shatterCountedLogVars (clauses); + compile (setOrNode->follow(), clauses); + *follow = setOrNode; + return true; + } + } + } + return false; +} + + + bool LiftedCircuit::tryGrounding ( CircuitNode**, @@ -638,11 +736,11 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) exportToGraphViz (*casted->rightBranch(), os); break; } - + case AND_NODE: { AndNode* casted = dynamic_cast(node); printClauses (casted, os); - + os << auxNode << " [label=\"∧\"]" << endl; os << escapeNode (node) << " -> " << auxNode; os << " [label=\"" << node->explanation() << "\"]" ; @@ -662,34 +760,47 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) exportToGraphViz (*casted->rightBranch(), os); break; } - + case SET_OR_NODE: { - // TODO - assert (false); - } - - case SET_AND_NODE: { - SetAndNode* casted = dynamic_cast(node); + SetOrNode* casted = dynamic_cast(node); printClauses (casted, os); - - os << auxNode << " [label=\"∧(X)\"]" << endl; + + os << auxNode << " [label=\"∨(X)\"]" << endl; os << escapeNode (node) << " -> " << auxNode; os << " [label=\"" << node->explanation() << "\"]" ; 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 << " [label=\"∧(X)\"]" << endl; + os << escapeNode (node) << " -> " << auxNode; + os << " [label=\"" << node->explanation() << "\"]" ; + 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 << " [label=\"IncExc\"]" << endl; os << escapeNode (node) << " -> " << auxNode; os << " [label=\"" << node->explanation() << "\"]" ; @@ -699,7 +810,7 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) os << escapeNode (*casted->plus1Branch()); os << " [label=\" " << (*casted->plus1Branch())->weight() << "\"]" ; os << endl; - + os << auxNode << " -> " ; os << escapeNode (*casted->plus2Branch()); os << " [label=\" " << (*casted->plus2Branch())->weight() << "\"]" ; @@ -709,35 +820,35 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) os << escapeNode (*casted->minusBranch()) << endl; os << " [label=\" " << (*casted->minusBranch())->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); } diff --git a/packages/CLPBN/horus/LiftedCircuit.h b/packages/CLPBN/horus/LiftedCircuit.h index f7db3d334..a89821c84 100644 --- a/packages/CLPBN/horus/LiftedCircuit.h +++ b/packages/CLPBN/horus/LiftedCircuit.h @@ -186,7 +186,7 @@ class CompilationFailedNode : public CircuitNode class LiftedCircuit { public: - LiftedCircuit (const LiftedWCNF* lwcnf); + LiftedCircuit (const LiftedWCNF* lwcnf); void smoothCircuit (void); @@ -205,8 +205,11 @@ class LiftedCircuit bool tryIndepPartialGrounding (CircuitNode** follow, Clauses& clauses); bool tryIndepPartialGroundingAux (Clauses& clauses, ConstraintTree& ct, vector& indices); + bool tryAtomCounting (CircuitNode** follow, Clauses& clauses); bool tryGrounding (CircuitNode** follow, Clauses& clauses); - + + void propagate (const Clause& c, const Clause& uc, Clauses& newClauses); + TinySet smoothCircuit (CircuitNode* node); void createSmoothNode (const TinySet& lids, diff --git a/packages/CLPBN/horus/LiftedWCNF.cpp b/packages/CLPBN/horus/LiftedWCNF.cpp index d69f4bd01..29affb2ac 100644 --- a/packages/CLPBN/horus/LiftedWCNF.cpp +++ b/packages/CLPBN/horus/LiftedWCNF.cpp @@ -17,7 +17,10 @@ Literal::isGround (ConstraintTree constr, LogVarSet ipgLogVars) const string -Literal::toString (LogVarSet ipgLogVars) const +Literal::toString ( + LogVarSet ipgLogVars, + LogVarSet posCountedLvs, + LogVarSet negCountedLvs) const { stringstream ss; negated_ ? ss << "¬" : ss << "" ; @@ -27,10 +30,14 @@ Literal::toString (LogVarSet ipgLogVars) const ss << "(" ; for (size_t i = 0; i < logVars_.size(); i++) { if (i != 0) ss << ","; - if (ipgLogVars.contains (logVars_[i])) { + 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", + "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "m" }; (X >= 12) ? ss << "x_" << X : ss << labels[X]; } else { @@ -66,10 +73,14 @@ Clause::containsLiteral (LiteralId lid) const bool -Clause::containsPositiveLiteral (LiteralId lid) const +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()) { + if (literals_[i].lid() == lid + && literals_[i].isPositive() + && logVarTypes (i) == types) { return true; } } @@ -79,10 +90,14 @@ Clause::containsPositiveLiteral (LiteralId lid) const bool -Clause::containsNegativeLiteral (LiteralId lid) const +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()) { + if (literals_[i].lid() == lid + && literals_[i].isNegative() + && logVarTypes (i) == types) { return true; } } @@ -107,11 +122,15 @@ Clause::removeLiterals (LiteralId lid) void -Clause::removePositiveLiterals (LiteralId lid) +Clause::removePositiveLiterals ( + LiteralId lid, + const LogVarTypes& types) { size_t i = 0; while (i != literals_.size()) { - if (literals_[i].lid() == lid && literals_[i].isPositive()) { + if (literals_[i].lid() == lid + && literals_[i].isPositive() + && logVarTypes (i) == types) { removeLiteral (i); } else { i ++; @@ -122,11 +141,15 @@ Clause::removePositiveLiterals (LiteralId lid) void -Clause::removeNegativeLiterals (LiteralId lid) +Clause::removeNegativeLiterals ( + LiteralId lid, + const LogVarTypes& types) { size_t i = 0; while (i != literals_.size()) { - if (literals_[i].lid() == lid && literals_[i].isNegative()) { + if (literals_[i].lid() == lid + && literals_[i].isNegative() + && logVarTypes (i) == types) { removeLiteral (i); } else { i ++; @@ -171,6 +194,34 @@ Clause::lidSet (void) const +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); +} + + + void Clause::removeLiteral (size_t idx) { @@ -182,6 +233,35 @@ Clause::removeLiteral (size_t idx) +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::printClauses (const Clauses& clauses) +{ + for (size_t i = 0; i < clauses.size(); i++) { + cout << clauses[i] << endl; + } +} + + + LogVarSet Clause::getLogVarSetExcluding (size_t idx) const { @@ -200,7 +280,8 @@ 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.ipgLogVars_); + os << clause.literals_[i].toString (clause.ipgLogVars_, + clause.posCountedLvs_, clause.negCountedLvs_); } if (clause.constr_.empty() == false) { ConstraintTree copy (clause.constr_); @@ -215,10 +296,23 @@ std::ostream& operator<< (ostream &os, const Clause& clause) LiftedWCNF::LiftedWCNF (const ParfactorList& pfList) : pfList_(pfList), freeLiteralId_(0) { - addIndicatorClauses (pfList); - addParameterClauses (pfList); + //addIndicatorClauses (pfList); + //addParameterClauses (pfList); + + vector> names = {{"p1","p1"},{"p2","p2"}}; + + Clause c1 (names); + c1.addLiteral (Literal (0, LogVars()={0})); + c1.addAndNegateLiteral (Literal (1, {0,1})); + clauses_.push_back(c1); + + Clause c2 (names); + c2.addLiteral (Literal (0, LogVars()={0})); + c2.addAndNegateLiteral (Literal (1, {1,0})); + clauses_.push_back(c2); + cout << "FORMULA INDICATORS:" << endl; - printFormulaIndicators(); + // printFormulaIndicators(); cout << endl; cout << "WEIGHTS:" << endl; printWeights(); diff --git a/packages/CLPBN/horus/LiftedWCNF.h b/packages/CLPBN/horus/LiftedWCNF.h index 89ebec029..079c07a11 100644 --- a/packages/CLPBN/horus/LiftedWCNF.h +++ b/packages/CLPBN/horus/LiftedWCNF.h @@ -10,6 +10,16 @@ typedef long LiteralId; class ConstraintTree; +enum LogVarType +{ + FULL_LV, + POS_LV, + NEG_LV +}; + + +typedef vector LogVarTypes; + class Literal { public: @@ -39,7 +49,9 @@ class Literal bool isGround (ConstraintTree constr, LogVarSet ipgLogVars) const; - string toString (LogVarSet ipgLogVars = LogVarSet()) const; + string toString (LogVarSet ipgLogVars = LogVarSet(), + LogVarSet posCountedLvs = LogVarSet(), + LogVarSet negCountedLvs = LogVarSet()) const; friend std::ostream& operator<< (ostream &os, const Literal& lit); @@ -58,6 +70,8 @@ class Clause public: Clause (const ConstraintTree& ct) : constr_(ct) { } + Clause (vector> names) : constr_(ConstraintTree (names)) { } + void addLiteral (const Literal& l) { literals_.push_back (l); } void addAndNegateLiteral (const Literal& l) @@ -68,15 +82,15 @@ class Clause bool containsLiteral (LiteralId lid) const; - bool containsPositiveLiteral (LiteralId lid) const; + bool containsPositiveLiteral (LiteralId lid, const LogVarTypes&) const; - bool containsNegativeLiteral (LiteralId lid) const; + bool containsNegativeLiteral (LiteralId lid, const LogVarTypes&) const; void removeLiterals (LiteralId lid); - void removePositiveLiterals (LiteralId lid); + void removePositiveLiterals (LiteralId lid, const LogVarTypes&); - void removeNegativeLiterals (LiteralId lid); + void removeNegativeLiterals (LiteralId lid, const LogVarTypes&); const vector& literals (void) const { return literals_; } @@ -92,20 +106,36 @@ class Clause void addIpgLogVar (LogVar X) { ipgLogVars_.insert (X); } + void addPositiveCountedLogVar (LogVar X) { posCountedLvs_.insert (X); } + + void addNegativeCountedLogVar (LogVar X) { negCountedLvs_.insert (X); } + LogVarSet ipgCandidates (void) const; TinySet lidSet (void) const; + bool isCountedLogVar (LogVar X) const; + + bool isPositiveCountedLogVar (LogVar X) const; + + bool isNegativeCountedLogVar (LogVar X) const; + friend std::ostream& operator<< (ostream &os, const Clause& clause); void removeLiteral (size_t idx); + LogVarTypes logVarTypes (size_t litIdx) const; + + static void printClauses (const vector& clauses); + private: LogVarSet getLogVarSetExcluding (size_t idx) const; vector literals_; LogVarSet ipgLogVars_; + LogVarSet posCountedLvs_; + LogVarSet negCountedLvs_; ConstraintTree constr_; }; From bfa9648067ef2ad6543f8d06916c7226324fe7b2 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Wed, 31 Oct 2012 23:58:07 +0000 Subject: [PATCH 18/52] clean up --- packages/CLPBN/horus/LiftedCircuit.cpp | 20 ----- packages/CLPBN/horus/LiftedCircuit.h | 8 +- packages/CLPBN/horus/LiftedWCNF.cpp | 111 +++++++++++++------------ packages/CLPBN/horus/LiftedWCNF.h | 75 ++++++++--------- 4 files changed, 96 insertions(+), 118 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index baa058170..06ebbae3e 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -217,23 +217,6 @@ LiftedCircuit::compile ( } -void -LiftedCircuit::propagate ( - const Clause& c, - const Clause& unitClause, - Clauses& newClauses) -{ -/* - Literals literals = c.literals(); - for (size_t i = 0; i < literals.size(); i++) { - if (literals_[i].lid() == lid && literals[i].isPositive()) { - - return true; - } - } -*/ -} - bool shatterCountedLogVars (Clauses& clauses, size_t idx1, size_t idx2) @@ -312,14 +295,12 @@ LiftedCircuit::tryUnitPropagation ( if (clauses[i].literals()[0].isPositive()) { if (clauses[j].containsPositiveLiteral (lid, types) == false) { Clause newClause = clauses[j]; - cout << "removing negative literals on " << newClause << endl; newClause.removeNegativeLiterals (lid, types); newClauses.push_back (newClause); } } else if (clauses[i].literals()[0].isNegative()) { if (clauses[j].containsNegativeLiteral (lid, types) == false) { Clause newClause = clauses[j]; - cout << "removing negative literals on " << newClause << endl; newClause.removePositiveLiterals (lid, types); newClauses.push_back (newClause); } @@ -330,7 +311,6 @@ LiftedCircuit::tryUnitPropagation ( explanation << " UP on" << clauses[i].literals()[0]; AndNode* andNode = new AndNode (clauses, explanation.str()); Clauses leftClauses = {clauses[i]}; - cout << "new clauses: " << newClauses << endl; compile (andNode->leftBranch(), leftClauses); compile (andNode->rightBranch(), newClauses); (*follow) = andNode; diff --git a/packages/CLPBN/horus/LiftedCircuit.h b/packages/CLPBN/horus/LiftedCircuit.h index a89821c84..060d66376 100644 --- a/packages/CLPBN/horus/LiftedCircuit.h +++ b/packages/CLPBN/horus/LiftedCircuit.h @@ -81,7 +81,7 @@ class AndNode : public CircuitNode double weight (void) const; - CircuitNode** leftBranch (void) { return &leftBranch_; } + CircuitNode** leftBranch (void) { return &leftBranch_; } CircuitNode** rightBranch (void) { return &rightBranch_; } private: CircuitNode* leftBranch_; @@ -128,12 +128,13 @@ class IncExcNode : public CircuitNode IncExcNode (const Clauses& clauses) : CircuitNode (clauses), plus1Branch_(0), plus2Branch_(0), minusBranch_(0) { } - + double weight (void) const; - + CircuitNode** plus1Branch (void) { return &plus1Branch_; } CircuitNode** plus2Branch (void) { return &plus2Branch_; } CircuitNode** minusBranch (void) { return &minusBranch_; } + private: CircuitNode* plus1Branch_; CircuitNode* plus2Branch_; @@ -172,7 +173,6 @@ class TrueNode : public CircuitNode - class CompilationFailedNode : public CircuitNode { public: diff --git a/packages/CLPBN/horus/LiftedWCNF.cpp b/packages/CLPBN/horus/LiftedWCNF.cpp index 29affb2ac..527035d08 100644 --- a/packages/CLPBN/horus/LiftedWCNF.cpp +++ b/packages/CLPBN/horus/LiftedWCNF.cpp @@ -159,41 +159,6 @@ Clause::removeNegativeLiterals ( -LogVarSet -Clause::ipgCandidates (void) const -{ - LogVarSet candidates; - LogVarSet allLvs = constr_.logVarSet(); - allLvs -= ipgLogVars_; - 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; -} - - - -TinySet -Clause::lidSet (void) const -{ - TinySet lidSet; - for (size_t i = 0; i < literals_.size(); i++) { - lidSet.insert (literals_[i].lid()); - } - return lidSet; -} - - - bool Clause::isCountedLogVar (LogVar X) const { @@ -222,13 +187,37 @@ Clause::isNegativeCountedLogVar (LogVar X) const -void -Clause::removeLiteral (size_t idx) +TinySet +Clause::lidSet (void) const { - LogVarSet lvs (literals_[idx].logVars()); - lvs -= getLogVarSetExcluding (idx); - constr_.remove (lvs); - literals_.erase (literals_.begin() + idx); + 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 -= ipgLogVars_; + 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; } @@ -252,6 +241,18 @@ Clause::logVarTypes (size_t litIdx) const +void +Clause::removeLiteral (size_t litIdx) +{ + // TODO maybe we need to clean up pos/neg/ipg lvs too + LogVarSet lvs (literals_[litIdx].logVars()); + lvs -= getLogVarSetExcluding (litIdx); + constr_.remove (lvs); + literals_.erase (literals_.begin() + litIdx); +} + + + void Clause::printClauses (const Clauses& clauses) { @@ -262,20 +263,6 @@ Clause::printClauses (const Clauses& clauses) -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<< (ostream &os, const Clause& clause) { for (unsigned i = 0; i < clause.literals_.size(); i++) { @@ -293,6 +280,20 @@ std::ostream& operator<< (ostream &os, const Clause& clause) +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; +} + + + LiftedWCNF::LiftedWCNF (const ParfactorList& pfList) : pfList_(pfList), freeLiteralId_(0) { diff --git a/packages/CLPBN/horus/LiftedWCNF.h b/packages/CLPBN/horus/LiftedWCNF.h index 079c07a11..260de8170 100644 --- a/packages/CLPBN/horus/LiftedWCNF.h +++ b/packages/CLPBN/horus/LiftedWCNF.h @@ -65,71 +65,70 @@ class Literal typedef vector Literals; + class Clause { public: Clause (const ConstraintTree& ct) : constr_(ct) { } - + Clause (vector> names) : constr_(ConstraintTree (names)) { } - + void addLiteral (const Literal& l) { literals_.push_back (l); } - + + // TODO kill me void addAndNegateLiteral (const Literal& l) { literals_.push_back (l); literals_.back().negate(); } - 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&); - const vector& literals (void) const { return literals_; } - - void removeLiteralByIndex (size_t idx) { literals_.erase (literals_.begin() + idx); } - + 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 ipgLogVars_; } - + void addIpgLogVar (LogVar X) { ipgLogVars_.insert (X); } - + void addPositiveCountedLogVar (LogVar X) { posCountedLvs_.insert (X); } void addNegativeCountedLogVar (LogVar X) { negCountedLvs_.insert (X); } - - LogVarSet ipgCandidates (void) const; + + 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; TinySet lidSet (void) const; + + LogVarSet ipgCandidates (void) const; + + LogVarTypes logVarTypes (size_t litIdx) const; - bool isCountedLogVar (LogVar X) const; - - bool isPositiveCountedLogVar (LogVar X) const; - - bool isNegativeCountedLogVar (LogVar X) const; + void removeLiteral (size_t litIdx); + + static void printClauses (const vector& clauses); friend std::ostream& operator<< (ostream &os, const Clause& clause); - void removeLiteral (size_t idx); - - LogVarTypes logVarTypes (size_t litIdx) const; - - static void printClauses (const vector& clauses); - private: - LogVarSet getLogVarSetExcluding (size_t idx) const; vector literals_; @@ -139,8 +138,6 @@ class Clause ConstraintTree constr_; }; - - typedef vector Clauses; From d4912ea21955561005f9a6eaf2bc815e9225101a Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Thu, 1 Nov 2012 13:56:12 +0000 Subject: [PATCH 19/52] some reorders --- packages/CLPBN/horus/LiftedCircuit.cpp | 119 +++++++++++++------------ packages/CLPBN/horus/LiftedCircuit.h | 15 +++- 2 files changed, 74 insertions(+), 60 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index 06ebbae3e..fa572db5e 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -218,64 +218,6 @@ LiftedCircuit::compile ( -bool -shatterCountedLogVars (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 (clauses[idx2]); - clauses[idx2].addPositiveCountedLogVar (lvs2[k]); - clauses.back().addNegativeCountedLogVar (lvs2[k]); - return true; - } - if (clauses[idx2].isCountedLogVar (lvs2[k]) - && clauses[idx1].isCountedLogVar (lvs1[k]) == false) { - clauses.push_back (clauses[idx1]); - clauses[idx1].addPositiveCountedLogVar (lvs1[k]); - clauses.back().addNegativeCountedLogVar (lvs1[k]); - return true; - } - } - } - } - } - return false; -} - - - -bool -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 = shatterCountedLogVars (clauses, i, j); - if (splitedSome) { - return true; - } - } - } - return false; -} - - - -void -shatterCountedLogVars (Clauses& clauses) -{ - while (shatterCountedLogVarsAux (clauses)) ; -} - - - bool LiftedCircuit::tryUnitPropagation ( CircuitNode** follow, @@ -562,6 +504,67 @@ LiftedCircuit::tryGrounding ( +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 (clauses[idx2]); + clauses[idx2].addPositiveCountedLogVar (lvs2[k]); + clauses.back().addNegativeCountedLogVar (lvs2[k]); + return true; + } + if (clauses[idx2].isCountedLogVar (lvs2[k]) + && clauses[idx1].isCountedLogVar (lvs1[k]) == false) { + clauses.push_back (clauses[idx1]); + clauses[idx1].addPositiveCountedLogVar (lvs1[k]); + clauses.back().addNegativeCountedLogVar (lvs1[k]); + return true; + } + } + } + } + } + return false; +} + + + TinySet LiftedCircuit::smoothCircuit (CircuitNode* node) { diff --git a/packages/CLPBN/horus/LiftedCircuit.h b/packages/CLPBN/horus/LiftedCircuit.h index 060d66376..a687a202f 100644 --- a/packages/CLPBN/horus/LiftedCircuit.h +++ b/packages/CLPBN/horus/LiftedCircuit.h @@ -199,16 +199,27 @@ class LiftedCircuit 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, vector& indices); + bool tryAtomCounting (CircuitNode** follow, Clauses& clauses); - bool tryGrounding (CircuitNode** follow, Clauses& clauses); + + bool tryGrounding (CircuitNode** follow, Clauses& clauses); + + void shatterCountedLogVars (Clauses& clauses); + + bool shatterCountedLogVarsAux (Clauses& clauses); - void propagate (const Clause& c, const Clause& uc, Clauses& newClauses); + bool shatterCountedLogVarsAux (Clauses& clauses, size_t idx1, size_t idx2); TinySet smoothCircuit (CircuitNode* node); From a1d0deb638d2808176b4748f9e17e9158d42d33b Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Thu, 1 Nov 2012 22:34:28 +0000 Subject: [PATCH 20/52] support model counting on atom couting nodes - still untested --- packages/CLPBN/horus/LiftedCircuit.cpp | 38 ++++++++++++----- packages/CLPBN/horus/LiftedCircuit.h | 47 +++++++++++++-------- packages/CLPBN/horus/LiftedWCNF.cpp | 4 +- packages/CLPBN/horus/LiftedWCNF.h | 58 ++++++++++++++------------ 4 files changed, 91 insertions(+), 56 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index fa572db5e..14203066a 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -26,13 +26,21 @@ AndNode::weight (void) const double SetOrNode::weight (void) const { - // TODO - return 0.0; + double weightSum = LogAware::addIdenty(); + for (unsigned i = 0; i < nrGroundings_ + 1; i++) { + nrGrsStack.push (make_pair (i, nrGroundings_ - i)); + if (Globals::logDomain) { + double w = std::log (Util::nrCombinations (nrGroundings_, i)); + weightSum = Util::logSum (weightSum, w + follow_->weight()); + } else { + weightSum += Util::nrCombinations (nrGroundings_, i) * follow_->weight(); + } + } + return weightSum; } - double SetAndNode::weight (void) const { @@ -67,14 +75,22 @@ LeafNode::weight (void) const assert (clauses()[0].isUnit()); Clause c = clauses()[0]; double weight = c.literals()[0].weight(); - LogVarSet lvs = c.constr().logVarSet() - c.ipgLogVars(); + LogVarSet lvs = c.constr().logVarSet(); + lvs -= c.ipgLogVars(); + lvs -= c.positiveCountedLogVars(); + lvs -= c.negativeCountedLogVars(); unsigned nrGroundings = 1; if (lvs.empty() == false) { ConstraintTree ct = c.constr(); ct.project (lvs); nrGroundings = ct.size(); } - assert (nrGroundings != 0); + // TODO this only works for one counted log var + if (c.positiveCountedLogVars().empty() == false) { + nrGroundings *= SetOrNode::nrPositives(); + } else if (c.negativeCountedLogVars().empty() == false) { + nrGroundings *= SetOrNode::nrNegatives(); + } return Globals::logDomain ? weight * nrGroundings : std::pow (weight, nrGroundings); @@ -85,6 +101,7 @@ LeafNode::weight (void) const double SmoothNode::weight (void) const { + // TODO and what happens if smoothing contains ipg or counted lvs ? Clauses cs = clauses(); double totalWeight = LogAware::multIdenty(); for (size_t i = 0; i < cs.size(); i++) { @@ -223,12 +240,11 @@ LiftedCircuit::tryUnitPropagation ( CircuitNode** follow, Clauses& clauses) { - cout << "ALL CLAUSES:" << endl; - Clause::printClauses (clauses); - + // cout << "ALL CLAUSES:" << endl; + // Clause::printClauses (clauses); for (size_t i = 0; i < clauses.size(); i++) { if (clauses[i].isUnit()) { - cout << clauses[i] << " is unit!" << endl; + // cout << clauses[i] << " is unit!" << endl; Clauses newClauses; for (size_t j = 0; j < clauses.size(); j++) { if (i != j) { @@ -453,7 +469,9 @@ LiftedCircuit::tryAtomCounting ( for (size_t j = 0; j < literals.size(); j++) { if (literals[j].logVars().size() == 1) { // TODO check if not already in ipg and countedlvs - SetOrNode* setOrNode = new SetOrNode (clauses); + unsigned nrGroundings = clauses[i].constr().projectedCopy ( + literals[j].logVars()).size(); + SetOrNode* setOrNode = new SetOrNode (nrGroundings, clauses); Clause c1 (clauses[i].constr().projectedCopy (literals[j].logVars())); Clause c2 (clauses[i].constr().projectedCopy (literals[j].logVars())); c1.addLiteral (literals[j]); diff --git a/packages/CLPBN/horus/LiftedCircuit.h b/packages/CLPBN/horus/LiftedCircuit.h index a687a202f..3688229cc 100644 --- a/packages/CLPBN/horus/LiftedCircuit.h +++ b/packages/CLPBN/horus/LiftedCircuit.h @@ -1,6 +1,8 @@ #ifndef HORUS_LIFTEDCIRCUIT_H #define HORUS_LIFTEDCIRCUIT_H +#include + #include "LiftedWCNF.h" @@ -45,11 +47,11 @@ class OrNode : public CircuitNode OrNode (const Clauses& clauses, string explanation = "") : CircuitNode (clauses, explanation), leftBranch_(0), rightBranch_(0) { } - - double weight (void) const; CircuitNode** leftBranch (void) { return &leftBranch_; } CircuitNode** rightBranch (void) { return &rightBranch_; } + + double weight (void) const; private: CircuitNode* leftBranch_; CircuitNode* rightBranch_; @@ -78,11 +80,12 @@ class AndNode : public CircuitNode string explanation = "") : CircuitNode ({}, explanation), leftBranch_(leftBranch), rightBranch_(rightBranch) { } - - double weight (void) const; CircuitNode** leftBranch (void) { return &leftBranch_; } CircuitNode** rightBranch (void) { return &rightBranch_; } + + double weight (void) const; + private: CircuitNode* leftBranch_; CircuitNode* rightBranch_; @@ -93,14 +96,23 @@ class AndNode : public CircuitNode class SetOrNode : public CircuitNode { public: - SetOrNode (const Clauses& clauses, string explanation = "") - : CircuitNode (clauses, explanation), follow_(0) { } - - double weight (void) const; - + SetOrNode (unsigned nrGroundings, const Clauses& clauses) + : CircuitNode (clauses, " AC"), follow_(0), + nrGroundings_(nrGroundings) { } + CircuitNode** follow (void) { return &follow_; } + + static unsigned nrPositives (void) { return nrGrsStack.top().first; } + + static unsigned nrNegatives (void) { return nrGrsStack.top().second; } + + double weight (void) const; + private: - CircuitNode* follow_; + CircuitNode* follow_; + unsigned nrGroundings_; + + static stack> nrGrsStack; }; @@ -109,15 +121,16 @@ class SetAndNode : public CircuitNode { public: SetAndNode (unsigned nrGroundings, const Clauses& clauses) - : CircuitNode (clauses, " IPG"), nrGroundings_(nrGroundings), - follow_(0) { } + : CircuitNode (clauses, " IPG"), follow_(0), + nrGroundings_(nrGroundings) { } + + CircuitNode** follow (void) { return &follow_; } double weight (void) const; - - CircuitNode** follow (void) { return &follow_; } + private: - unsigned nrGroundings_; CircuitNode* follow_; + unsigned nrGroundings_; }; @@ -129,11 +142,11 @@ class IncExcNode : public CircuitNode : CircuitNode (clauses), plus1Branch_(0), plus2Branch_(0), minusBranch_(0) { } - double weight (void) const; - CircuitNode** plus1Branch (void) { return &plus1Branch_; } CircuitNode** plus2Branch (void) { return &plus2Branch_; } CircuitNode** minusBranch (void) { return &minusBranch_; } + + double weight (void) const; private: CircuitNode* plus1Branch_; diff --git a/packages/CLPBN/horus/LiftedWCNF.cpp b/packages/CLPBN/horus/LiftedWCNF.cpp index 527035d08..e9003405c 100644 --- a/packages/CLPBN/horus/LiftedWCNF.cpp +++ b/packages/CLPBN/horus/LiftedWCNF.cpp @@ -119,7 +119,7 @@ Clause::removeLiterals (LiteralId lid) } } - + void Clause::removePositiveLiterals ( @@ -137,7 +137,7 @@ Clause::removePositiveLiterals ( } } } - + void diff --git a/packages/CLPBN/horus/LiftedWCNF.h b/packages/CLPBN/horus/LiftedWCNF.h index 260de8170..ac8a8758f 100644 --- a/packages/CLPBN/horus/LiftedWCNF.h +++ b/packages/CLPBN/horus/LiftedWCNF.h @@ -25,36 +25,36 @@ class Literal public: Literal (LiteralId lid, double w = -1.0) : lid_(lid), weight_(w), negated_(false) { } - + Literal (LiteralId lid, const LogVars& lvs, double w = -1.0) : lid_(lid), logVars_(lvs), weight_(w), negated_(false) { } - + Literal (const Literal& lit, bool negated) : lid_(lit.lid_), logVars_(lit.logVars_), weight_(lit.weight_), negated_(negated) { } LiteralId lid (void) const { return lid_; } - + LogVars logVars (void) const { return logVars_; } - + LogVarSet logVarSet (void) const { return LogVarSet (logVars_); } // FIXME this is not log aware :( double weight (void) const { return weight_ < 0.0 ? 1.0 : weight_; } - + void negate (void) { negated_ = !negated_; } bool isPositive (void) const { return negated_ == false; } - + bool isNegative (void) const { return negated_; } - + bool isGround (ConstraintTree constr, LogVarSet ipgLogVars) const; - + string toString (LogVarSet ipgLogVars = LogVarSet(), LogVarSet posCountedLvs = LogVarSet(), LogVarSet negCountedLvs = LogVarSet()) const; - + friend std::ostream& operator<< (ostream &os, const Literal& lit); - + private: LiteralId lid_; LogVars logVars_; @@ -81,7 +81,7 @@ class Clause literals_.push_back (l); literals_.back().negate(); } - + const vector& literals (void) const { return literals_; } const ConstraintTree& constr (void) const { return constr_; } @@ -98,6 +98,10 @@ class Clause void addNegativeCountedLogVar (LogVar X) { negCountedLvs_.insert (X); } + LogVarSet positiveCountedLogVars (void) const { return posCountedLvs_; } + + LogVarSet negativeCountedLogVars (void) const { return negCountedLvs_; } + bool containsLiteral (LiteralId lid) const; bool containsPositiveLiteral (LiteralId lid, const LogVarTypes&) const; @@ -115,26 +119,26 @@ class Clause bool isPositiveCountedLogVar (LogVar X) const; bool isNegativeCountedLogVar (LogVar X) const; - + TinySet lidSet (void) const; LogVarSet ipgCandidates (void) const; LogVarTypes logVarTypes (size_t litIdx) const; - + void removeLiteral (size_t litIdx); - + static void printClauses (const vector& clauses); friend std::ostream& operator<< (ostream &os, const Clause& clause); - + private: LogVarSet getLogVarSetExcluding (size_t idx) const; - + vector literals_; LogVarSet ipgLogVars_; LogVarSet posCountedLvs_; - LogVarSet negCountedLvs_; + LogVarSet negCountedLvs_; ConstraintTree constr_; }; @@ -146,19 +150,19 @@ class LiftedWCNF { public: LiftedWCNF (const ParfactorList& pfList); - + ~LiftedWCNF (void); - + const Clauses& clauses (void) const { return clauses_; } - + Clause createClauseForLiteral (LiteralId lid) const; - + void printFormulaIndicators (void) const; - + void printWeights (void) const; - + void printClauses (void) const; - + private: void addIndicatorClauses (const ParfactorList& pfList); @@ -171,11 +175,11 @@ class LiftedWCNF } Clauses clauses_; - + unordered_map> map_; - + const ParfactorList& pfList_; - + LiteralId freeLiteralId_; }; From b8cef8798a8eeaa39e3da74aaaef52aa78819867 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Thu, 1 Nov 2012 22:54:14 +0000 Subject: [PATCH 21/52] fix warning produced by new version of gcc --- packages/CLPBN/horus/LiftedVe.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/CLPBN/horus/LiftedVe.h b/packages/CLPBN/horus/LiftedVe.h index d09762dac..e79ffc265 100644 --- a/packages/CLPBN/horus/LiftedVe.h +++ b/packages/CLPBN/horus/LiftedVe.h @@ -8,6 +8,8 @@ class LiftedOperator { public: + virtual ~LiftedOperator (void) { } + virtual double getLogCost (void) = 0; virtual void apply (void) = 0; From 4518a3db5d579c0d4eb7edecc8fc06f4a847af97 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Sun, 4 Nov 2012 18:02:40 +0000 Subject: [PATCH 22/52] support smoothing on atom counting nodes (beta) --- packages/CLPBN/horus/LiftedCircuit.cpp | 169 +++++++++++++++++++++---- packages/CLPBN/horus/LiftedCircuit.h | 4 +- packages/CLPBN/horus/LiftedWCNF.cpp | 8 +- packages/CLPBN/horus/LiftedWCNF.h | 32 +++++ 4 files changed, 181 insertions(+), 32 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index 14203066a..26989dbf4 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -23,6 +23,10 @@ AndNode::weight (void) const +stack> SetOrNode::nrGrsStack; + + + double SetOrNode::weight (void) const { @@ -583,82 +587,195 @@ LiftedCircuit::shatterCountedLogVarsAux ( -TinySet +LogVarTypes +unionTypes (const LogVarTypes& types1, const LogVarTypes& types2) +{ + if (types1.empty()) { + return types2; + } + if (types2.empty()) { + return types1; + } + assert (types1.size() == types2.size()); + LogVarTypes res; + for (size_t i = 0; i < types1.size(); i++) { + if (types1[i] == LogVarType::POS_LV + && types2[i] == LogVarType::POS_LV) { + res.push_back (LogVarType::POS_LV); + } else if (types1[i] == LogVarType::NEG_LV + && types2[i] == LogVarType::NEG_LV) { + res.push_back (LogVarType::NEG_LV); + } else { + res.push_back (LogVarType::FULL_LV); + } + } + return res; +} + + + +vector +getAllPossibleTypes (unsigned nrLogVars) +{ + if (nrLogVars == 0) { + return {}; + } + if (nrLogVars == 1) { + return {{LogVarType::POS_LV},{LogVarType::NEG_LV}}; + } + vector res; + Indexer indexer (vector (nrLogVars, 2)); + 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 +containsTypes (const LogVarTypes& typesA, const LogVarTypes& typesB) +{ + 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; +} + + + +LitLvTypesSet LiftedCircuit::smoothCircuit (CircuitNode* node) { assert (node != 0); - TinySet propagatingLids; + LitLvTypesSet propagLits; switch (getCircuitNodeType (node)) { case CircuitNodeType::OR_NODE: { OrNode* casted = dynamic_cast(node); - TinySet lids1 = smoothCircuit (*casted->leftBranch()); - TinySet lids2 = smoothCircuit (*casted->rightBranch()); - TinySet missingLeft = lids2 - lids1; - TinySet missingRight = lids1 - lids2; + 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()); - propagatingLids |= lids1; - propagatingLids |= lids2; + propagLits |= lids1; + propagLits |= lids2; break; } case CircuitNodeType::AND_NODE: { AndNode* casted = dynamic_cast(node); - TinySet lids1 = smoothCircuit (*casted->leftBranch()); - TinySet lids2 = smoothCircuit (*casted->rightBranch()); - propagatingLids |= lids1; - propagatingLids |= lids2; + LitLvTypesSet lids1 = smoothCircuit (*casted->leftBranch()); + LitLvTypesSet lids2 = smoothCircuit (*casted->rightBranch()); + propagLits |= lids1; + propagLits |= lids2; break; } case CircuitNodeType::SET_OR_NODE: { - // TODO + 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 (allTypes[j], propagLits[k].logVarTypes())) { + typeFound = true; + break; + } + } + if (typeFound == false) { + missingLids.insert (LiteralLvTypes (litSet[i].first, allTypes[j])); + } + } + } + createSmoothNode (missingLids, casted->follow()); + // TODO change propagLits to full lvs break; } case CircuitNodeType::SET_AND_NODE: { SetAndNode* casted = dynamic_cast(node); - propagatingLids = smoothCircuit (*casted->follow()); + propagLits = smoothCircuit (*casted->follow()); break; } case CircuitNodeType::INC_EXC_NODE: { IncExcNode* casted = dynamic_cast(node); - TinySet lids1 = smoothCircuit (*casted->plus1Branch()); - TinySet lids2 = smoothCircuit (*casted->plus2Branch()); - TinySet missingPlus1 = lids2 - lids1; - TinySet missingPlus2 = lids1 - lids2; + 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()); - propagatingLids |= lids1; - propagatingLids |= lids2; + propagLits |= lids1; + propagLits |= lids2; break; } case CircuitNodeType::LEAF_NODE: { - propagatingLids.insert (node->clauses()[0].literals()[0].lid()); + propagLits.insert (LiteralLvTypes ( + node->clauses()[0].literals()[0].lid(), + node->clauses()[0].logVarTypes(0))); } default: break; } - return propagatingLids; + return propagLits; } void LiftedCircuit::createSmoothNode ( - const TinySet& missingLids, + const LitLvTypesSet& missingLits, CircuitNode** prev) { - if (missingLids.empty() == false) { + if (missingLits.empty() == false) { Clauses clauses; - for (size_t i = 0; i < missingLids.size(); i++) { - Clause c = lwcnf_->createClauseForLiteral (missingLids[i]); + for (size_t i = 0; i < missingLits.size(); i++) { + LiteralId lid = missingLits[i].lid(); + const LogVarTypes& types = missingLits[i].logVarTypes(); + Clause c = lwcnf_->createClauseForLiteral (lid); + for (size_t j = 0; j < types.size(); j++) { + LogVar X = c.literals().front().logVars()[j]; + if (types[j] == LogVarType::POS_LV) { + c.addPositiveCountedLogVar (X); + } else if (types[j] == LogVarType::NEG_LV) { + c.addNegativeCountedLogVar (X); + } + } c.addAndNegateLiteral (c.literals()[0]); clauses.push_back (c); } diff --git a/packages/CLPBN/horus/LiftedCircuit.h b/packages/CLPBN/horus/LiftedCircuit.h index 3688229cc..accc52f72 100644 --- a/packages/CLPBN/horus/LiftedCircuit.h +++ b/packages/CLPBN/horus/LiftedCircuit.h @@ -234,9 +234,9 @@ class LiftedCircuit bool shatterCountedLogVarsAux (Clauses& clauses, size_t idx1, size_t idx2); - TinySet smoothCircuit (CircuitNode* node); + LitLvTypesSet smoothCircuit (CircuitNode* node); - void createSmoothNode (const TinySet& lids, + void createSmoothNode (const LitLvTypesSet& lids, CircuitNode** prev); CircuitNodeType getCircuitNodeType (const CircuitNode* node) const; diff --git a/packages/CLPBN/horus/LiftedWCNF.cpp b/packages/CLPBN/horus/LiftedWCNF.cpp index e9003405c..290bdf274 100644 --- a/packages/CLPBN/horus/LiftedWCNF.cpp +++ b/packages/CLPBN/horus/LiftedWCNF.cpp @@ -303,13 +303,13 @@ LiftedWCNF::LiftedWCNF (const ParfactorList& pfList) vector> names = {{"p1","p1"},{"p2","p2"}}; Clause c1 (names); - c1.addLiteral (Literal (0, LogVars()={0})); - c1.addAndNegateLiteral (Literal (1, {0,1})); + c1.addLiteral (Literal (0, LogVars()={0}, 3.0)); + c1.addAndNegateLiteral (Literal (1, {0,1}, 1.0)); clauses_.push_back(c1); Clause c2 (names); - c2.addLiteral (Literal (0, LogVars()={0})); - c2.addAndNegateLiteral (Literal (1, {1,0})); + c2.addLiteral (Literal (0, LogVars()={0}, 2.0)); + c2.addAndNegateLiteral (Literal (1, {1,0}, 5.0)); clauses_.push_back(c2); cout << "FORMULA INDICATORS:" << endl; diff --git a/packages/CLPBN/horus/LiftedWCNF.h b/packages/CLPBN/horus/LiftedWCNF.h index ac8a8758f..43a3afa30 100644 --- a/packages/CLPBN/horus/LiftedWCNF.h +++ b/packages/CLPBN/horus/LiftedWCNF.h @@ -146,6 +146,38 @@ typedef vector Clauses; +class LiteralLvTypes +{ + public: + struct CompareLiteralLvTypes + { + bool operator() ( + const LiteralLvTypes& types1, + const LiteralLvTypes& types2) const + { + if (types1.lid_ < types2.lid_) { + return true; + } + return types1.lvTypes_ < types2.lvTypes_; + } + }; + + LiteralLvTypes (LiteralId lid, const LogVarTypes& lvTypes) : + lid_(lid), lvTypes_(lvTypes) { } + + LiteralId lid (void) const { return lid_; } + + const LogVarTypes& logVarTypes (void) const { return lvTypes_; } + + private: + LiteralId lid_; + LogVarTypes lvTypes_; +}; + +typedef TinySet LitLvTypesSet; + + + class LiftedWCNF { public: From ab334f82b207c019c310f855f9ec2f67157fa5ff Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Tue, 6 Nov 2012 14:15:21 +0000 Subject: [PATCH 23/52] fix weighted model counting in atom counting nodes --- packages/CLPBN/horus/LiftedCircuit.cpp | 94 +++++++++++++--------- packages/CLPBN/horus/LiftedCircuit.h | 16 +++- packages/CLPBN/horus/LiftedWCNF.cpp | 103 +++++++++++++------------ packages/CLPBN/horus/LiftedWCNF.h | 59 +++++++++----- 4 files changed, 162 insertions(+), 110 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index 26989dbf4..18cda5c15 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -32,12 +32,20 @@ SetOrNode::weight (void) const { double weightSum = LogAware::addIdenty(); for (unsigned i = 0; i < nrGroundings_ + 1; i++) { - nrGrsStack.push (make_pair (i, nrGroundings_ - i)); + nrGrsStack.push (make_pair (nrGroundings_ - i, i)); if (Globals::logDomain) { double w = std::log (Util::nrCombinations (nrGroundings_, i)); weightSum = Util::logSum (weightSum, w + follow_->weight()); } else { - weightSum += Util::nrCombinations (nrGroundings_, i) * follow_->weight(); + cout << endl; + cout << "nr groundings = " << nrGroundings_ << endl; + cout << "nr positives = " << nrPositives() << endl; + cout << "nr negatives = " << nrNegatives() << endl; + cout << "i = " << i << endl; + cout << "nr combos = " << Util::nrCombinations (nrGroundings_, i) << endl; + double w = follow_->weight(); + cout << "weight = " << w << endl; + weightSum += Util::nrCombinations (nrGroundings_, i) * w; } } return weightSum; @@ -78,7 +86,9 @@ LeafNode::weight (void) const assert (clauses().size() == 1); assert (clauses()[0].isUnit()); Clause c = clauses()[0]; - double weight = c.literals()[0].weight(); + double weight = c.literals()[0].isPositive() + ? lwcnf_.posWeight (c.literals().front().lid()) + : lwcnf_.negWeight (c.literals().front().lid()); LogVarSet lvs = c.constr().logVarSet(); lvs -= c.ipgLogVars(); lvs -= c.positiveCountedLogVars(); @@ -90,11 +100,20 @@ LeafNode::weight (void) const nrGroundings = ct.size(); } // TODO this only works for one counted log var + cout << "calc weight for " << clauses().front() << endl; if (c.positiveCountedLogVars().empty() == false) { - nrGroundings *= SetOrNode::nrPositives(); - } else if (c.negativeCountedLogVars().empty() == false) { - nrGroundings *= SetOrNode::nrNegatives(); + cout << " -> nr pos = " << SetOrNode::nrPositives() << endl; + nrGroundings *= std::pow (SetOrNode::nrPositives(), + c.nrPositiveCountedLogVars()); } + if (c.negativeCountedLogVars().empty() == false) { + cout << " -> nr neg = " << SetOrNode::nrNegatives() << endl; + nrGroundings *= std::pow (SetOrNode::nrNegatives(), + c.nrNegativeCountedLogVars()); + } + cout << " -> nr groundings = " << nrGroundings << endl; + cout << " -> lit weight = " << weight << endl; + cout << " -> ret weight = " << std::pow (weight, nrGroundings) << endl; return Globals::logDomain ? weight * nrGroundings : std::pow (weight, nrGroundings); @@ -109,14 +128,38 @@ SmoothNode::weight (void) const Clauses cs = clauses(); double totalWeight = LogAware::multIdenty(); for (size_t i = 0; i < cs.size(); i++) { - double posWeight = cs[i].literals()[0].weight(); - double negWeight = cs[i].literals()[1].weight(); - unsigned nrGroundings = cs[i].constr().size(); + 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].positiveCountedLogVars(); + lvs -= cs[i].negativeCountedLogVars(); + unsigned nrGroundings = 1; + if (lvs.empty() == false) { + ConstraintTree ct = cs[i].constr(); + ct.project (lvs); + nrGroundings = ct.size(); + } + cout << "calc smooth weight for " << cs[i] << endl; + if (cs[i].positiveCountedLogVars().empty() == false) { + cout << " -> nr pos = " << SetOrNode::nrPositives() << endl; + nrGroundings *= std::pow (SetOrNode::nrPositives(), + cs[i].nrPositiveCountedLogVars()); + } + if (cs[i].negativeCountedLogVars().empty() == false) { + cout << " -> nr neg = " << SetOrNode::nrNegatives() << endl; + nrGroundings *= std::pow (SetOrNode::nrNegatives(), + cs[i].nrNegativeCountedLogVars()); + } + cout << " -> pos+neg = " << posWeight + negWeight << endl; + cout << " -> nrgroun = " << nrGroundings << endl; if (Globals::logDomain) { + // TODO i think i have to do log on nrGrounginds here! totalWeight += (Util::logSum (posWeight, negWeight) * nrGroundings); } else { totalWeight *= std::pow (posWeight + negWeight, nrGroundings); } + cout << " -> smooth weight = " << totalWeight << endl; } return totalWeight; } @@ -151,6 +194,8 @@ LiftedCircuit::LiftedCircuit (const LiftedWCNF* lwcnf) exportToGraphViz("circuit.dot"); smoothCircuit(); exportToGraphViz("circuit.smooth.dot"); + cout << "--------------------------------------------------" << endl; + cout << "--------------------------------------------------" << endl; cout << "WEIGHTED MODEL COUNT = " << getWeightedModelCount() << endl; } @@ -201,7 +246,7 @@ LiftedCircuit::compile ( } if (clauses.size() == 1 && clauses[0].isUnit()) { - *follow = new LeafNode (clauses[0]); + *follow = new LeafNode (clauses[0], *lwcnf_); return; } @@ -587,33 +632,6 @@ LiftedCircuit::shatterCountedLogVarsAux ( -LogVarTypes -unionTypes (const LogVarTypes& types1, const LogVarTypes& types2) -{ - if (types1.empty()) { - return types2; - } - if (types2.empty()) { - return types1; - } - assert (types1.size() == types2.size()); - LogVarTypes res; - for (size_t i = 0; i < types1.size(); i++) { - if (types1[i] == LogVarType::POS_LV - && types2[i] == LogVarType::POS_LV) { - res.push_back (LogVarType::POS_LV); - } else if (types1[i] == LogVarType::NEG_LV - && types2[i] == LogVarType::NEG_LV) { - res.push_back (LogVarType::NEG_LV); - } else { - res.push_back (LogVarType::FULL_LV); - } - } - return res; -} - - - vector getAllPossibleTypes (unsigned nrLogVars) { @@ -779,7 +797,7 @@ LiftedCircuit::createSmoothNode ( c.addAndNegateLiteral (c.literals()[0]); clauses.push_back (c); } - SmoothNode* smoothNode = new SmoothNode (clauses); + SmoothNode* smoothNode = new SmoothNode (clauses, *lwcnf_); *prev = new AndNode ((*prev)->clauses(), smoothNode, *prev, " Smoothing"); } diff --git a/packages/CLPBN/horus/LiftedCircuit.h b/packages/CLPBN/horus/LiftedCircuit.h index accc52f72..903b9e73f 100644 --- a/packages/CLPBN/horus/LiftedCircuit.h +++ b/packages/CLPBN/horus/LiftedCircuit.h @@ -159,9 +159,13 @@ class IncExcNode : public CircuitNode class LeafNode : public CircuitNode { public: - LeafNode (const Clause& clause) : CircuitNode ({clause}) { } - + LeafNode (const Clause& clause, const LiftedWCNF& lwcnf) + : CircuitNode (Clauses() = {clause}), lwcnf_(lwcnf) { } + double weight (void) const; + + private: + const LiftedWCNF& lwcnf_; }; @@ -169,9 +173,13 @@ class LeafNode : public CircuitNode class SmoothNode : public CircuitNode { public: - SmoothNode (const Clauses& clauses) : CircuitNode (clauses) { } - + SmoothNode (const Clauses& clauses, const LiftedWCNF& lwcnf) + : CircuitNode (clauses), lwcnf_(lwcnf) { } + double weight (void) const; + + private: + const LiftedWCNF& lwcnf_; }; diff --git a/packages/CLPBN/horus/LiftedWCNF.cpp b/packages/CLPBN/horus/LiftedWCNF.cpp index 290bdf274..83b52c3cc 100644 --- a/packages/CLPBN/horus/LiftedWCNF.cpp +++ b/packages/CLPBN/horus/LiftedWCNF.cpp @@ -3,6 +3,7 @@ #include "Indexer.h" + bool Literal::isGround (ConstraintTree constr, LogVarSet ipgLogVars) const { @@ -24,7 +25,12 @@ Literal::toString ( { stringstream ss; negated_ ? ss << "¬" : ss << "" ; - weight_ < 0.0 ? ss << "λ" : ss << "Θ" ; + // if (negated_ == false) { + // posWeight_ < 0.0 ? ss << "λ" : ss << "Θ" ; + // } else { + // negWeight_ < 0.0 ? ss << "λ" : ss << "Θ" ; + // } + ss << "λ" ; ss << lid_ ; if (logVars_.empty() == false) { ss << "(" ; @@ -300,18 +306,44 @@ LiftedWCNF::LiftedWCNF (const ParfactorList& pfList) //addIndicatorClauses (pfList); //addParameterClauses (pfList); - vector> names = {{"p1","p1"},{"p2","p2"}}; + vector> names = { +/* + {"p1","p1"}, + {"p1","p2"}, + {"p2","p1"}, + {"p2","p2"}, + {"p1","p3"}, + {"p2","p3"}, + {"p3","p3"}, + {"p3","p2"}, + {"p3","p1"} +*/ + {"p1","p1"}, + {"p1","p2"}, + {"p1","p3"}, + {"p2","p1"}, + {"p2","p2"}, + {"p2","p3"}, + {"p3","p1"}, + {"p3","p2"}, + {"p3","p3"} + }; Clause c1 (names); - c1.addLiteral (Literal (0, LogVars()={0}, 3.0)); - c1.addAndNegateLiteral (Literal (1, {0,1}, 1.0)); + c1.addLiteral (Literal (0, LogVars() = {0})); + c1.addAndNegateLiteral (Literal (1, {0,1})); clauses_.push_back(c1); Clause c2 (names); - c2.addLiteral (Literal (0, LogVars()={0}, 2.0)); - c2.addAndNegateLiteral (Literal (1, {1,0}, 5.0)); + c2.addLiteral (Literal (0, LogVars()={0})); + c2.addAndNegateLiteral (Literal (1, {1,0})); clauses_.push_back(c2); + addWeight (0, 3.0, 4.0); + addWeight (1, 2.0, 5.0); + + freeLiteralId_ = 2; + cout << "FORMULA INDICATORS:" << endl; // printFormulaIndicators(); cout << endl; @@ -320,6 +352,7 @@ LiftedWCNF::LiftedWCNF (const ParfactorList& pfList) cout << endl; cout << "CLAUSES:" << endl; printClauses(); + // abort(); cout << endl; } @@ -349,7 +382,7 @@ LiftedWCNF::createClauseForLiteral (LiteralId lid) const } // FIXME Clause c (ConstraintTree({})); - c.addLiteral (Literal (lid,{})); + c.addLiteral (Literal (lid,LogVars() = {})); return c; //assert (false); //return Clause (0); @@ -410,22 +443,25 @@ LiftedWCNF::addParameterClauses (const ParfactorList& pfList) // ¬λu1 ... ¬λun v θxi|u1,...,un -> clause1 // ¬θxi|u1,...,un v λu1 -> tempClause // ¬θxi|u1,...,un v λu2 -> tempClause - double weight = (**it)[indexer]; + double posWeight = (**it)[indexer]; + addWeight (paramVarLid, posWeight, 1.0); Clause clause1 (*(*it)->constr()); for (unsigned i = 0; i < groups.size(); i++) { LiteralId lid = getLiteralId (groups[i], indexer[i]); - clause1.addAndNegateLiteral (Literal (lid, (*it)->argument(i).logVars())); + clause1.addAndNegateLiteral ( + Literal (lid, (*it)->argument(i).logVars())); ConstraintTree ct = *(*it)->constr(); Clause tempClause (ct); - tempClause.addAndNegateLiteral (Literal (paramVarLid, (*it)->constr()->logVars(), 1.0)); + tempClause.addAndNegateLiteral (Literal ( + paramVarLid, (*it)->constr()->logVars())); tempClause.addLiteral (Literal (lid, (*it)->argument(i).logVars())); clauses_.push_back (tempClause); } - clause1.addLiteral (Literal (paramVarLid, (*it)->constr()->logVars(),weight)); + clause1.addLiteral (Literal (paramVarLid, (*it)->constr()->logVars())); clauses_.push_back (clause1); freeLiteralId_ ++; ++ indexer; @@ -464,43 +500,14 @@ LiftedWCNF::printFormulaIndicators (void) const void LiftedWCNF::printWeights (void) const { - for (LiteralId i = 0; i < freeLiteralId_; i++) { - - bool found = false; - for (size_t j = 0; j < clauses_.size(); j++) { - Literals literals = clauses_[j].literals(); - for (size_t k = 0; k < literals.size(); k++) { - if (literals[k].lid() == i && literals[k].isPositive()) { - cout << "weight(" << literals[k] << ") = " ; - cout << literals[k].weight(); - cout << endl; - found = true; - break; - } - } - if (found == true) { - break; - } - } - - found = false; - for (size_t j = 0; j < clauses_.size(); j++) { - Literals literals = clauses_[j].literals(); - for (size_t k = 0; k < literals.size(); k++) { - if (literals[k].lid() == i && literals[k].isNegative()) { - cout << "weight(" << literals[k] << ") = " ; - cout << literals[k].weight(); - cout << endl; - found = true; - break; - } - } - if (found == true) { - break; - } - } - - } + 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; + } } diff --git a/packages/CLPBN/horus/LiftedWCNF.h b/packages/CLPBN/horus/LiftedWCNF.h index 43a3afa30..781cd4111 100644 --- a/packages/CLPBN/horus/LiftedWCNF.h +++ b/packages/CLPBN/horus/LiftedWCNF.h @@ -23,14 +23,11 @@ typedef vector LogVarTypes; class Literal { public: - Literal (LiteralId lid, double w = -1.0) : - lid_(lid), weight_(w), negated_(false) { } - - Literal (LiteralId lid, const LogVars& lvs, double w = -1.0) : - lid_(lid), logVars_(lvs), weight_(w), negated_(false) { } + Literal (LiteralId lid, const LogVars& lvs) : + lid_(lid), logVars_(lvs), negated_(false) { } Literal (const Literal& lit, bool negated) : - lid_(lit.lid_), logVars_(lit.logVars_), weight_(lit.weight_), negated_(negated) { } + lid_(lit.lid_), logVars_(lit.logVars_), negated_(negated) { } LiteralId lid (void) const { return lid_; } @@ -38,15 +35,12 @@ class Literal LogVarSet logVarSet (void) const { return LogVarSet (logVars_); } - // FIXME this is not log aware :( - double weight (void) const { return weight_ < 0.0 ? 1.0 : weight_; } - void negate (void) { negated_ = !negated_; } bool isPositive (void) const { return negated_ == false; } bool isNegative (void) const { return negated_; } - + bool isGround (ConstraintTree constr, LogVarSet ipgLogVars) const; string toString (LogVarSet ipgLogVars = LogVarSet(), @@ -58,7 +52,6 @@ class Literal private: LiteralId lid_; LogVars logVars_; - double weight_; bool negated_; }; @@ -102,6 +95,10 @@ class Clause LogVarSet negativeCountedLogVars (void) const { return negCountedLvs_; } + unsigned nrPositiveCountedLogVars (void) const { return posCountedLvs_.size(); } + + unsigned nrNegativeCountedLogVars (void) const { return negCountedLvs_.size(); } + bool containsLiteral (LiteralId lid) const; bool containsPositiveLiteral (LiteralId lid, const LogVarTypes&) const; @@ -184,32 +181,54 @@ class LiftedWCNF LiftedWCNF (const ParfactorList& pfList); ~LiftedWCNF (void); + + const Clauses& clauses (void) const { return clauses_; } + + double posWeight (LiteralId lid) const + { + unordered_map>::const_iterator it; + it = weights_.find (lid); + return it != weights_.end() ? it->second.first : 1.0; + } - const Clauses& clauses (void) const { return clauses_; } + double negWeight (LiteralId lid) const + { + unordered_map>::const_iterator it; + it = weights_.find (lid); + return it != weights_.end() ? it->second.second : 1.0; + } - Clause createClauseForLiteral (LiteralId lid) const; + Clause createClauseForLiteral (LiteralId lid) const; - void printFormulaIndicators (void) const; + void printFormulaIndicators (void) const; - void printWeights (void) const; + void printWeights (void) const; - void printClauses (void) const; + void printClauses (void) const; private: - void addIndicatorClauses (const ParfactorList& pfList); - - void addParameterClauses (const ParfactorList& pfList); - + LiteralId getLiteralId (PrvGroup prvGroup, unsigned range) { assert (Util::contains (map_, prvGroup)); return map_[prvGroup][range]; } + + void addWeight (LiteralId lid, double posW, double negW) + { + weights_[lid] = make_pair (posW, negW); + } + + void addIndicatorClauses (const ParfactorList& pfList); + + void addParameterClauses (const ParfactorList& pfList); Clauses clauses_; unordered_map> map_; + unordered_map> weights_; + const ParfactorList& pfList_; LiteralId freeLiteralId_; From 5e1547ba780ebeb5d241b4b3513492a39507a34e Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Tue, 6 Nov 2012 15:15:55 +0000 Subject: [PATCH 24/52] add missing method to TinySet --- packages/CLPBN/horus/TinySet.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/CLPBN/horus/TinySet.h b/packages/CLPBN/horus/TinySet.h index 2c7d113b4..ed810bcde 100644 --- a/packages/CLPBN/horus/TinySet.h +++ b/packages/CLPBN/horus/TinySet.h @@ -153,6 +153,11 @@ class TinySet { return vec_[i]; } + + T& operator[] (typename vector::size_type i) + { + return vec_[i]; + } T front (void) const { From 869d513c1a5c56510e5786d434485bab8c2f1b3c Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Tue, 6 Nov 2012 15:56:52 +0000 Subject: [PATCH 25/52] remove and add some TODOs --- packages/CLPBN/horus/LiftedCircuit.cpp | 50 +++++++++++++------------- packages/CLPBN/horus/LiftedWCNF.cpp | 21 +++++++---- packages/CLPBN/horus/LiftedWCNF.h | 8 +++-- 3 files changed, 47 insertions(+), 32 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index 18cda5c15..d2a2ab4bc 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -99,21 +99,20 @@ LeafNode::weight (void) const ct.project (lvs); nrGroundings = ct.size(); } - // TODO this only works for one counted log var - cout << "calc weight for " << clauses().front() << endl; + // cout << "calc weight for " << clauses().front() << endl; if (c.positiveCountedLogVars().empty() == false) { - cout << " -> nr pos = " << SetOrNode::nrPositives() << endl; + // cout << " -> nr pos = " << SetOrNode::nrPositives() << endl; nrGroundings *= std::pow (SetOrNode::nrPositives(), c.nrPositiveCountedLogVars()); } if (c.negativeCountedLogVars().empty() == false) { - cout << " -> nr neg = " << SetOrNode::nrNegatives() << endl; + //cout << " -> nr neg = " << SetOrNode::nrNegatives() << endl; nrGroundings *= std::pow (SetOrNode::nrNegatives(), c.nrNegativeCountedLogVars()); } - cout << " -> nr groundings = " << nrGroundings << endl; - cout << " -> lit weight = " << weight << endl; - cout << " -> ret weight = " << std::pow (weight, nrGroundings) << endl; + // cout << " -> nr groundings = " << nrGroundings << endl; + // cout << " -> lit weight = " << weight << endl; + // cout << " -> ret weight = " << std::pow (weight, nrGroundings) << endl; return Globals::logDomain ? weight * nrGroundings : std::pow (weight, nrGroundings); @@ -124,7 +123,6 @@ LeafNode::weight (void) const double SmoothNode::weight (void) const { - // TODO and what happens if smoothing contains ipg or counted lvs ? Clauses cs = clauses(); double totalWeight = LogAware::multIdenty(); for (size_t i = 0; i < cs.size(); i++) { @@ -140,26 +138,26 @@ SmoothNode::weight (void) const ct.project (lvs); nrGroundings = ct.size(); } - cout << "calc smooth weight for " << cs[i] << endl; + // cout << "calc smooth weight for " << cs[i] << endl; if (cs[i].positiveCountedLogVars().empty() == false) { - cout << " -> nr pos = " << SetOrNode::nrPositives() << endl; + // cout << " -> nr pos = " << SetOrNode::nrPositives() << endl; nrGroundings *= std::pow (SetOrNode::nrPositives(), cs[i].nrPositiveCountedLogVars()); } if (cs[i].negativeCountedLogVars().empty() == false) { - cout << " -> nr neg = " << SetOrNode::nrNegatives() << endl; + // cout << " -> nr neg = " << SetOrNode::nrNegatives() << endl; nrGroundings *= std::pow (SetOrNode::nrNegatives(), cs[i].nrNegativeCountedLogVars()); } - cout << " -> pos+neg = " << posWeight + negWeight << endl; - cout << " -> nrgroun = " << nrGroundings << endl; + // cout << " -> pos+neg = " << posWeight + negWeight << endl; + // cout << " -> nrgroun = " << nrGroundings << endl; if (Globals::logDomain) { - // TODO i think i have to do log on nrGrounginds here! - totalWeight += (Util::logSum (posWeight, negWeight) * nrGroundings); + totalWeight += (Util::logSum (posWeight, negWeight) + * std::log (nrGroundings)); } else { totalWeight *= std::pow (posWeight + negWeight, nrGroundings); } - cout << " -> smooth weight = " << totalWeight << endl; + // cout << " -> smooth weight = " << totalWeight << endl; } return totalWeight; } @@ -337,7 +335,7 @@ LiftedCircuit::tryIndependence ( if (clauses.size() == 1) { return false; } - // TODO this independence is a little weak + // TODO compare all subsets with all subsets for (size_t i = 0; i < clauses.size(); i++) { bool indep = true; TinySet lids1 = clauses[i].lidSet(); @@ -407,6 +405,7 @@ LiftedCircuit::tryInclusionExclusion ( CircuitNode** follow, Clauses& clauses) { + // TODO compare all subsets with all subsets for (size_t i = 0; i < clauses.size(); i++) { const Literals& literals = clauses[i].literals(); for (size_t j = 0; j < literals.size(); j++) { @@ -420,8 +419,7 @@ LiftedCircuit::tryInclusionExclusion ( } } if (indep) { - // TODO i am almost sure that this will - // have to be count normalized too! + // TODO this should be have to be count normalized too ConstraintTree really = clauses[i].constr(); Clause c1 (really.projectedCopy ( literals[j].logVars())); @@ -489,6 +487,7 @@ LiftedCircuit::tryIndepPartialGroundingAux ( ConstraintTree& ct, vector& lvIndices) { + // TODO check if the ipg log vars appears in the same positions for (size_t j = 1; j < clauses.size(); j++) { LogVarSet lvs2 = clauses[j].ipgCandidates(); for (size_t k = 0; k < lvs2.size(); k++) { @@ -516,15 +515,16 @@ LiftedCircuit::tryAtomCounting ( 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].logVars().size() == 1) { - // TODO check if not already in ipg and countedlvs + if (literals[j].logVars().size() == 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, clauses); Clause c1 (clauses[i].constr().projectedCopy (literals[j].logVars())); Clause c2 (clauses[i].constr().projectedCopy (literals[j].logVars())); c1.addLiteral (literals[j]); - c2.addAndNegateLiteral (literals[j]); + c2.addLiteralNegated (literals[j]); c1.addPositiveCountedLogVar (literals[j].logVars().front()); c2.addNegativeCountedLogVar (literals[j].logVars().front()); clauses.push_back (c1); @@ -737,7 +737,9 @@ LiftedCircuit::smoothCircuit (CircuitNode* node) } } createSmoothNode (missingLids, casted->follow()); - // TODO change propagLits to full lvs + for (size_t i = 0; i < propagLits.size(); i++) { + propagLits[i].setAllFullLogVars(); + } break; } @@ -794,7 +796,7 @@ LiftedCircuit::createSmoothNode ( c.addNegativeCountedLogVar (X); } } - c.addAndNegateLiteral (c.literals()[0]); + c.addLiteralNegated (c.literals()[0]); clauses.push_back (c); } SmoothNode* smoothNode = new SmoothNode (clauses, *lwcnf_); diff --git a/packages/CLPBN/horus/LiftedWCNF.cpp b/packages/CLPBN/horus/LiftedWCNF.cpp index 83b52c3cc..c28b3c732 100644 --- a/packages/CLPBN/horus/LiftedWCNF.cpp +++ b/packages/CLPBN/horus/LiftedWCNF.cpp @@ -193,6 +193,15 @@ Clause::isNegativeCountedLogVar (LogVar X) const +bool +Clause::isIpgLogVar (LogVar X) const +{ + assert (constr_.logVarSet().contains (X)); + return ipgLogVars_.contains (X); +} + + + TinySet Clause::lidSet (void) const { @@ -331,12 +340,12 @@ LiftedWCNF::LiftedWCNF (const ParfactorList& pfList) Clause c1 (names); c1.addLiteral (Literal (0, LogVars() = {0})); - c1.addAndNegateLiteral (Literal (1, {0,1})); + c1.addLiteralNegated (Literal (1, {0,1})); clauses_.push_back(c1); Clause c2 (names); c2.addLiteral (Literal (0, LogVars()={0})); - c2.addAndNegateLiteral (Literal (1, {1,0})); + c2.addLiteralNegated (Literal (1, {1,0})); clauses_.push_back(c2); addWeight (0, 3.0, 4.0); @@ -415,8 +424,8 @@ LiftedWCNF::addIndicatorClauses (const ParfactorList& pfList) ConstraintTree tempConstr2 = *(*it)->constr(); tempConstr2.project (formulas[i].logVars()); Clause clause2 (tempConstr2); - clause2.addAndNegateLiteral (Literal (clause.literals()[j])); - clause2.addAndNegateLiteral (Literal (clause.literals()[k])); + clause2.addLiteralNegated (Literal (clause.literals()[j])); + clause2.addLiteralNegated (Literal (clause.literals()[k])); clauses_.push_back (clause2); } } @@ -451,12 +460,12 @@ LiftedWCNF::addParameterClauses (const ParfactorList& pfList) for (unsigned i = 0; i < groups.size(); i++) { LiteralId lid = getLiteralId (groups[i], indexer[i]); - clause1.addAndNegateLiteral ( + clause1.addLiteralNegated ( Literal (lid, (*it)->argument(i).logVars())); ConstraintTree ct = *(*it)->constr(); Clause tempClause (ct); - tempClause.addAndNegateLiteral (Literal ( + tempClause.addLiteralNegated (Literal ( paramVarLid, (*it)->constr()->logVars())); tempClause.addLiteral (Literal (lid, (*it)->argument(i).logVars())); clauses_.push_back (tempClause); diff --git a/packages/CLPBN/horus/LiftedWCNF.h b/packages/CLPBN/horus/LiftedWCNF.h index 781cd4111..a5b7547bc 100644 --- a/packages/CLPBN/horus/LiftedWCNF.h +++ b/packages/CLPBN/horus/LiftedWCNF.h @@ -68,8 +68,7 @@ class Clause void addLiteral (const Literal& l) { literals_.push_back (l); } - // TODO kill me - void addAndNegateLiteral (const Literal& l) + void addLiteralNegated (const Literal& l) { literals_.push_back (l); literals_.back().negate(); @@ -116,6 +115,8 @@ class Clause bool isPositiveCountedLogVar (LogVar X) const; bool isNegativeCountedLogVar (LogVar X) const; + + bool isIpgLogVar (LogVar X) const; TinySet lidSet (void) const; @@ -165,6 +166,9 @@ class LiteralLvTypes LiteralId lid (void) const { return lid_; } const LogVarTypes& logVarTypes (void) const { return lvTypes_; } + + void setAllFullLogVars (void) { + lvTypes_ = LogVarTypes (lvTypes_.size(), LogVarType::FULL_LV); } private: LiteralId lid_; From 1e38743462dba4ebfd6395d894dbe5dc27ca606b Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Tue, 6 Nov 2012 16:24:59 +0000 Subject: [PATCH 26/52] fix ipgCandidates --- packages/CLPBN/horus/LiftedWCNF.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/CLPBN/horus/LiftedWCNF.cpp b/packages/CLPBN/horus/LiftedWCNF.cpp index c28b3c732..0dac99a06 100644 --- a/packages/CLPBN/horus/LiftedWCNF.cpp +++ b/packages/CLPBN/horus/LiftedWCNF.cpp @@ -220,6 +220,8 @@ Clause::ipgCandidates (void) const LogVarSet candidates; LogVarSet allLvs = constr_.logVarSet(); allLvs -= ipgLogVars_; + 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++) { From 06a59ad6590b9771788cab23bbf946fe3e76b2c3 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Tue, 6 Nov 2012 23:35:14 +0000 Subject: [PATCH 27/52] IPG: verify that the root log vars appear in the same positions --- packages/CLPBN/horus/LiftedCircuit.cpp | 56 ++++++++++++++++---------- packages/CLPBN/horus/LiftedCircuit.h | 2 +- packages/CLPBN/horus/LiftedWCNF.cpp | 16 ++++++-- packages/CLPBN/horus/LiftedWCNF.h | 4 ++ 4 files changed, 52 insertions(+), 26 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index d2a2ab4bc..763d8aae1 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -264,9 +264,9 @@ LiftedCircuit::compile ( return; } - //if (tryIndepPartialGrounding (follow, clauses)) { - // return; - //} + if (tryIndepPartialGrounding (follow, clauses)) { + return; + } if (tryAtomCounting (follow, clauses)) { return; @@ -457,18 +457,16 @@ LiftedCircuit::tryIndepPartialGrounding ( { // assumes that all literals have logical variables // else, shannon decomp was possible - vector lvIndices; + LogVars rootLogVars; LogVarSet lvs = clauses[0].ipgCandidates(); for (size_t i = 0; i < lvs.size(); i++) { - lvIndices.clear(); - lvIndices.push_back (i); - ConstraintTree ct = clauses[0].constr(); - ct.project ({lvs[i]}); - if (tryIndepPartialGroundingAux (clauses, ct, lvIndices)) { + rootLogVars.clear(); + rootLogVars.push_back (lvs[i]); + ConstraintTree ct = clauses[0].constr().projectedCopy ({lvs[i]}); + if (tryIndepPartialGroundingAux (clauses, ct, rootLogVars)) { Clauses newClauses = clauses; - for (size_t i = 0; i < clauses.size(); i++) { - LogVar lv = clauses[i].ipgCandidates()[lvIndices[i]]; - newClauses[i].addIpgLogVar (lv); + for (size_t j = 0; j < clauses.size(); j++) { + newClauses[j].addIpgLogVar (rootLogVars[j]); } SetAndNode* node = new SetAndNode (ct.size(), clauses); *follow = node; @@ -485,23 +483,39 @@ bool LiftedCircuit::tryIndepPartialGroundingAux ( Clauses& clauses, ConstraintTree& ct, - vector& lvIndices) + LogVars& rootLogVars) { - // TODO check if the ipg log vars appears in the same positions - for (size_t j = 1; j < clauses.size(); j++) { - LogVarSet lvs2 = clauses[j].ipgCandidates(); - for (size_t k = 0; k < lvs2.size(); k++) { - ConstraintTree ct2 = clauses[j].constr(); - ct2.project ({lvs2[k]}); + 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()) { - lvIndices.push_back (k); + rootLogVars.push_back (lvs[j]); break; } } - if (lvIndices.size() != j+1) { + 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; } diff --git a/packages/CLPBN/horus/LiftedCircuit.h b/packages/CLPBN/horus/LiftedCircuit.h index 903b9e73f..cfa3a713b 100644 --- a/packages/CLPBN/horus/LiftedCircuit.h +++ b/packages/CLPBN/horus/LiftedCircuit.h @@ -230,7 +230,7 @@ class LiftedCircuit bool tryIndepPartialGrounding (CircuitNode** follow, Clauses& clauses); bool tryIndepPartialGroundingAux (Clauses& clauses, ConstraintTree& ct, - vector& indices); + LogVars& rootLogVars); bool tryAtomCounting (CircuitNode** follow, Clauses& clauses); diff --git a/packages/CLPBN/horus/LiftedWCNF.cpp b/packages/CLPBN/horus/LiftedWCNF.cpp index 0dac99a06..07595a22f 100644 --- a/packages/CLPBN/horus/LiftedWCNF.cpp +++ b/packages/CLPBN/horus/LiftedWCNF.cpp @@ -17,6 +17,14 @@ Literal::isGround (ConstraintTree constr, LogVarSet ipgLogVars) const +size_t +Literal::indexOfLogVar (LogVar X) const +{ + return Util::indexOf (logVars_, X); +} + + + string Literal::toString ( LogVarSet ipgLogVars, @@ -344,17 +352,17 @@ LiftedWCNF::LiftedWCNF (const ParfactorList& pfList) c1.addLiteral (Literal (0, LogVars() = {0})); c1.addLiteralNegated (Literal (1, {0,1})); clauses_.push_back(c1); - + Clause c2 (names); c2.addLiteral (Literal (0, LogVars()={0})); c2.addLiteralNegated (Literal (1, {1,0})); clauses_.push_back(c2); - + addWeight (0, 3.0, 4.0); addWeight (1, 2.0, 5.0); - + freeLiteralId_ = 2; - + cout << "FORMULA INDICATORS:" << endl; // printFormulaIndicators(); cout << endl; diff --git a/packages/CLPBN/horus/LiftedWCNF.h b/packages/CLPBN/horus/LiftedWCNF.h index a5b7547bc..7220b0823 100644 --- a/packages/CLPBN/horus/LiftedWCNF.h +++ b/packages/CLPBN/horus/LiftedWCNF.h @@ -34,6 +34,8 @@ class Literal LogVars logVars (void) const { return logVars_; } LogVarSet logVarSet (void) const { return LogVarSet (logVars_); } + + size_t nrLogVars (void) const { return logVars_.size(); } void negate (void) { negated_ = !negated_; } @@ -42,6 +44,8 @@ class Literal 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(), From 829f2248eebe421a9671824b4200d28685e6549d Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Tue, 6 Nov 2012 23:39:18 +0000 Subject: [PATCH 28/52] use utility method --- packages/CLPBN/horus/LiftedCircuit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index 763d8aae1..01847dc26 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -529,7 +529,7 @@ LiftedCircuit::tryAtomCounting ( 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].logVars().size() == 1 + 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 ( From b599b45bc66b6c8e6ed416086e9d7714637029c3 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Tue, 6 Nov 2012 23:56:52 +0000 Subject: [PATCH 29/52] AC: only allow one counting node per branch --- packages/CLPBN/horus/LiftedCircuit.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index 01847dc26..eb1dec42e 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -526,6 +526,13 @@ LiftedCircuit::tryAtomCounting ( CircuitNode** follow, Clauses& clauses) { + for (size_t i = 0; i < clauses.size(); i++) { + if (clauses[i].nrPositiveCountedLogVars() > 0 + || clauses[i].nrNegativeCountedLogVars() > 0) { + // only allow one atom counting node per branch + return false; + } + } for (size_t i = 0; i < clauses.size(); i++) { Literals literals = clauses[i].literals(); for (size_t j = 0; j < literals.size(); j++) { From 83c1e586748c5b4b927c708b14ebe987cfa869ab Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Wed, 7 Nov 2012 12:37:22 +0000 Subject: [PATCH 30/52] clean ups --- packages/CLPBN/horus/LiftedCircuit.cpp | 100 +++++++++++++------------ packages/CLPBN/horus/LiftedCircuit.h | 9 ++- 2 files changed, 58 insertions(+), 51 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index eb1dec42e..22bf1286e 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -653,55 +653,6 @@ LiftedCircuit::shatterCountedLogVarsAux ( -vector -getAllPossibleTypes (unsigned nrLogVars) -{ - if (nrLogVars == 0) { - return {}; - } - if (nrLogVars == 1) { - return {{LogVarType::POS_LV},{LogVarType::NEG_LV}}; - } - vector res; - Indexer indexer (vector (nrLogVars, 2)); - 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 -containsTypes (const LogVarTypes& typesA, const LogVarTypes& typesB) -{ - 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; -} - - - LitLvTypesSet LiftedCircuit::smoothCircuit (CircuitNode* node) { @@ -828,6 +779,57 @@ LiftedCircuit::createSmoothNode ( +vector +LiftedCircuit::getAllPossibleTypes (unsigned nrLogVars) const +{ + if (nrLogVars == 0) { + return {}; + } + if (nrLogVars == 1) { + return {{LogVarType::POS_LV},{LogVarType::NEG_LV}}; + } + vector res; + Indexer indexer (vector (nrLogVars, 2)); + 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 { diff --git a/packages/CLPBN/horus/LiftedCircuit.h b/packages/CLPBN/horus/LiftedCircuit.h index cfa3a713b..d5f1556f1 100644 --- a/packages/CLPBN/horus/LiftedCircuit.h +++ b/packages/CLPBN/horus/LiftedCircuit.h @@ -221,9 +221,9 @@ class LiftedCircuit bool tryUnitPropagation (CircuitNode** follow, Clauses& clauses); - bool tryIndependence (CircuitNode** follow, Clauses& clauses); + bool tryIndependence (CircuitNode** follow, Clauses& clauses); - bool tryShannonDecomp (CircuitNode** follow, Clauses& clauses); + bool tryShannonDecomp (CircuitNode** follow, Clauses& clauses); bool tryInclusionExclusion (CircuitNode** follow, Clauses& clauses); @@ -247,6 +247,11 @@ class LiftedCircuit 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&); From 07c6509a792a9e04ecd550a744681bf9dade7ca4 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Wed, 7 Nov 2012 15:28:33 +0000 Subject: [PATCH 31/52] cleanups, refactorings & renamings --- packages/CLPBN/horus/LiftedCircuit.cpp | 54 +++++++------- packages/CLPBN/horus/LiftedWCNF.cpp | 71 +++++++++++++++---- packages/CLPBN/horus/LiftedWCNF.h | 98 ++++++++++---------------- 3 files changed, 121 insertions(+), 102 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index 22bf1286e..43036626a 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -91,8 +91,8 @@ LeafNode::weight (void) const : lwcnf_.negWeight (c.literals().front().lid()); LogVarSet lvs = c.constr().logVarSet(); lvs -= c.ipgLogVars(); - lvs -= c.positiveCountedLogVars(); - lvs -= c.negativeCountedLogVars(); + lvs -= c.posCountedLogVars(); + lvs -= c.negCountedLogVars(); unsigned nrGroundings = 1; if (lvs.empty() == false) { ConstraintTree ct = c.constr(); @@ -100,15 +100,15 @@ LeafNode::weight (void) const nrGroundings = ct.size(); } // cout << "calc weight for " << clauses().front() << endl; - if (c.positiveCountedLogVars().empty() == false) { + if (c.posCountedLogVars().empty() == false) { // cout << " -> nr pos = " << SetOrNode::nrPositives() << endl; nrGroundings *= std::pow (SetOrNode::nrPositives(), - c.nrPositiveCountedLogVars()); + c.nrPosCountedLogVars()); } - if (c.negativeCountedLogVars().empty() == false) { + if (c.negCountedLogVars().empty() == false) { //cout << " -> nr neg = " << SetOrNode::nrNegatives() << endl; nrGroundings *= std::pow (SetOrNode::nrNegatives(), - c.nrNegativeCountedLogVars()); + c.nrNegCountedLogVars()); } // cout << " -> nr groundings = " << nrGroundings << endl; // cout << " -> lit weight = " << weight << endl; @@ -130,8 +130,8 @@ SmoothNode::weight (void) const double negWeight = lwcnf_.negWeight (cs[i].literals()[0].lid()); LogVarSet lvs = cs[i].constr().logVarSet(); lvs -= cs[i].ipgLogVars(); - lvs -= cs[i].positiveCountedLogVars(); - lvs -= cs[i].negativeCountedLogVars(); + lvs -= cs[i].posCountedLogVars(); + lvs -= cs[i].negCountedLogVars(); unsigned nrGroundings = 1; if (lvs.empty() == false) { ConstraintTree ct = cs[i].constr(); @@ -139,15 +139,15 @@ SmoothNode::weight (void) const nrGroundings = ct.size(); } // cout << "calc smooth weight for " << cs[i] << endl; - if (cs[i].positiveCountedLogVars().empty() == false) { + if (cs[i].posCountedLogVars().empty() == false) { // cout << " -> nr pos = " << SetOrNode::nrPositives() << endl; nrGroundings *= std::pow (SetOrNode::nrPositives(), - cs[i].nrPositiveCountedLogVars()); + cs[i].nrPosCountedLogVars()); } - if (cs[i].negativeCountedLogVars().empty() == false) { + if (cs[i].negCountedLogVars().empty() == false) { // cout << " -> nr neg = " << SetOrNode::nrNegatives() << endl; nrGroundings *= std::pow (SetOrNode::nrNegatives(), - cs[i].nrNegativeCountedLogVars()); + cs[i].nrNegCountedLogVars()); } // cout << " -> pos+neg = " << posWeight + negWeight << endl; // cout << " -> nrgroun = " << nrGroundings << endl; @@ -527,8 +527,8 @@ LiftedCircuit::tryAtomCounting ( Clauses& clauses) { for (size_t i = 0; i < clauses.size(); i++) { - if (clauses[i].nrPositiveCountedLogVars() > 0 - || clauses[i].nrNegativeCountedLogVars() > 0) { + if (clauses[i].nrPosCountedLogVars() > 0 + || clauses[i].nrNegCountedLogVars() > 0) { // only allow one atom counting node per branch return false; } @@ -545,9 +545,9 @@ LiftedCircuit::tryAtomCounting ( Clause c1 (clauses[i].constr().projectedCopy (literals[j].logVars())); Clause c2 (clauses[i].constr().projectedCopy (literals[j].logVars())); c1.addLiteral (literals[j]); - c2.addLiteralNegated (literals[j]); - c1.addPositiveCountedLogVar (literals[j].logVars().front()); - c2.addNegativeCountedLogVar (literals[j].logVars().front()); + 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); @@ -633,15 +633,15 @@ LiftedCircuit::shatterCountedLogVarsAux ( if (clauses[idx1].isCountedLogVar (lvs1[k]) && clauses[idx2].isCountedLogVar (lvs2[k]) == false) { clauses.push_back (clauses[idx2]); - clauses[idx2].addPositiveCountedLogVar (lvs2[k]); - clauses.back().addNegativeCountedLogVar (lvs2[k]); + 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 (clauses[idx1]); - clauses[idx1].addPositiveCountedLogVar (lvs1[k]); - clauses.back().addNegativeCountedLogVar (lvs1[k]); + clauses[idx1].addPosCountedLogVar (lvs1[k]); + clauses.back().addNegCountedLogVar (lvs1[k]); return true; } } @@ -704,7 +704,7 @@ LiftedCircuit::smoothCircuit (CircuitNode* node) } } if (typeFound == false) { - missingLids.insert (LiteralLvTypes (litSet[i].first, allTypes[j])); + missingLids.insert (LitLvTypes (litSet[i].first, allTypes[j])); } } } @@ -735,7 +735,7 @@ LiftedCircuit::smoothCircuit (CircuitNode* node) } case CircuitNodeType::LEAF_NODE: { - propagLits.insert (LiteralLvTypes ( + propagLits.insert (LitLvTypes ( node->clauses()[0].literals()[0].lid(), node->clauses()[0].logVarTypes(0))); } @@ -759,16 +759,16 @@ LiftedCircuit::createSmoothNode ( for (size_t i = 0; i < missingLits.size(); i++) { LiteralId lid = missingLits[i].lid(); const LogVarTypes& types = missingLits[i].logVarTypes(); - Clause c = lwcnf_->createClauseForLiteral (lid); + 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.addPositiveCountedLogVar (X); + c.addPosCountedLogVar (X); } else if (types[j] == LogVarType::NEG_LV) { - c.addNegativeCountedLogVar (X); + c.addNegCountedLogVar (X); } } - c.addLiteralNegated (c.literals()[0]); + c.addLiteralComplemented (c.literals()[0]); clauses.push_back (c); } SmoothNode* smoothNode = new SmoothNode (clauses, *lwcnf_); diff --git a/packages/CLPBN/horus/LiftedWCNF.cpp b/packages/CLPBN/horus/LiftedWCNF.cpp index 07595a22f..6585947de 100644 --- a/packages/CLPBN/horus/LiftedWCNF.cpp +++ b/packages/CLPBN/horus/LiftedWCNF.cpp @@ -73,6 +73,16 @@ std::ostream& operator<< (ostream &os, const Literal& lit) +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 { @@ -320,7 +330,7 @@ Clause::getLogVarSetExcluding (size_t idx) const LiftedWCNF::LiftedWCNF (const ParfactorList& pfList) - : pfList_(pfList), freeLiteralId_(0) + : freeLiteralId_(0), pfList_(pfList) { //addIndicatorClauses (pfList); //addParameterClauses (pfList); @@ -350,12 +360,12 @@ LiftedWCNF::LiftedWCNF (const ParfactorList& pfList) Clause c1 (names); c1.addLiteral (Literal (0, LogVars() = {0})); - c1.addLiteralNegated (Literal (1, {0,1})); + c1.addLiteralComplemented (Literal (1, {0,1})); clauses_.push_back(c1); Clause c2 (names); c2.addLiteral (Literal (0, LogVars()={0})); - c2.addLiteralNegated (Literal (1, {1,0})); + c2.addLiteralComplemented (Literal (1, {1,0})); clauses_.push_back(c2); addWeight (0, 3.0, 4.0); @@ -384,8 +394,28 @@ LiftedWCNF::~LiftedWCNF (void) +double +LiftedWCNF::posWeight (LiteralId lid) const +{ + unordered_map>::const_iterator it; + it = weights_.find (lid); + return it != weights_.end() ? it->second.first : 1.0; +} + + + +double +LiftedWCNF::negWeight (LiteralId lid) const +{ + unordered_map>::const_iterator it; + it = weights_.find (lid); + return it != weights_.end() ? it->second.second : 1.0; +} + + + Clause -LiftedWCNF::createClauseForLiteral (LiteralId lid) const +LiftedWCNF::createClause (LiteralId lid) const { for (size_t i = 0; i < clauses_.size(); i++) { const Literals& literals = clauses_[i].literals(); @@ -399,12 +429,25 @@ LiftedWCNF::createClauseForLiteral (LiteralId lid) const } } } - // FIXME - Clause c (ConstraintTree({})); - c.addLiteral (Literal (lid,LogVars() = {})); - return c; - //assert (false); - //return Clause (0); + abort(); // we should not reach this point + return Clause (ConstraintTree({})); +} + + + +LiteralId +LiftedWCNF::getLiteralId (PrvGroup prvGroup, unsigned range) +{ + assert (Util::contains (map_, prvGroup)); + return map_[prvGroup][range]; +} + + + +void +LiftedWCNF::addWeight (LiteralId lid, double posW, double negW) +{ + weights_[lid] = make_pair (posW, negW); } @@ -434,8 +477,8 @@ LiftedWCNF::addIndicatorClauses (const ParfactorList& pfList) ConstraintTree tempConstr2 = *(*it)->constr(); tempConstr2.project (formulas[i].logVars()); Clause clause2 (tempConstr2); - clause2.addLiteralNegated (Literal (clause.literals()[j])); - clause2.addLiteralNegated (Literal (clause.literals()[k])); + clause2.addLiteralComplemented (Literal (clause.literals()[j])); + clause2.addLiteralComplemented (Literal (clause.literals()[k])); clauses_.push_back (clause2); } } @@ -470,12 +513,12 @@ LiftedWCNF::addParameterClauses (const ParfactorList& pfList) for (unsigned i = 0; i < groups.size(); i++) { LiteralId lid = getLiteralId (groups[i], indexer[i]); - clause1.addLiteralNegated ( + clause1.addLiteralComplemented ( Literal (lid, (*it)->argument(i).logVars())); ConstraintTree ct = *(*it)->constr(); Clause tempClause (ct); - tempClause.addLiteralNegated (Literal ( + tempClause.addLiteralComplemented (Literal ( paramVarLid, (*it)->constr()->logVars())); tempClause.addLiteral (Literal (lid, (*it)->argument(i).logVars())); clauses_.push_back (tempClause); diff --git a/packages/CLPBN/horus/LiftedWCNF.h b/packages/CLPBN/horus/LiftedWCNF.h index 7220b0823..f56b2c090 100644 --- a/packages/CLPBN/horus/LiftedWCNF.h +++ b/packages/CLPBN/horus/LiftedWCNF.h @@ -17,9 +17,10 @@ enum LogVarType NEG_LV }; - typedef vector LogVarTypes; + + class Literal { public: @@ -32,12 +33,12 @@ class Literal 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_); } - - size_t nrLogVars (void) const { return logVars_.size(); } - - void negate (void) { negated_ = !negated_; } + + void complement (void) { negated_ = !negated_; } bool isPositive (void) const { return negated_ == false; } @@ -51,12 +52,12 @@ class Literal LogVarSet posCountedLvs = LogVarSet(), LogVarSet negCountedLvs = LogVarSet()) const; - friend std::ostream& operator<< (ostream &os, const Literal& lit); + friend std::ostream& operator<< (std::ostream &os, const Literal& lit); private: - LiteralId lid_; - LogVars logVars_; - bool negated_; + LiteralId lid_; + LogVars logVars_; + bool negated_; }; typedef vector Literals; @@ -72,13 +73,7 @@ class Clause void addLiteral (const Literal& l) { literals_.push_back (l); } - void addLiteralNegated (const Literal& l) - { - literals_.push_back (l); - literals_.back().negate(); - } - - const vector& literals (void) const { return literals_; } + const Literals& literals (void) const { return literals_; } const ConstraintTree& constr (void) const { return constr_; } @@ -90,17 +85,19 @@ class Clause void addIpgLogVar (LogVar X) { ipgLogVars_.insert (X); } - void addPositiveCountedLogVar (LogVar X) { posCountedLvs_.insert (X); } + void addPosCountedLogVar (LogVar X) { posCountedLvs_.insert (X); } - void addNegativeCountedLogVar (LogVar X) { negCountedLvs_.insert (X); } + void addNegCountedLogVar (LogVar X) { negCountedLvs_.insert (X); } - LogVarSet positiveCountedLogVars (void) const { return posCountedLvs_; } + LogVarSet posCountedLogVars (void) const { return posCountedLvs_; } - LogVarSet negativeCountedLogVars (void) const { return negCountedLvs_; } + LogVarSet negCountedLogVars (void) const { return negCountedLvs_; } - unsigned nrPositiveCountedLogVars (void) const { return posCountedLvs_.size(); } + unsigned nrPosCountedLogVars (void) const { return posCountedLvs_.size(); } - unsigned nrNegativeCountedLogVars (void) const { return negCountedLvs_.size(); } + unsigned nrNegCountedLogVars (void) const { return negCountedLvs_.size(); } + + void addLiteralComplemented (const Literal& lit); bool containsLiteral (LiteralId lid) const; @@ -137,7 +134,7 @@ class Clause private: LogVarSet getLogVarSetExcluding (size_t idx) const; - vector literals_; + Literals literals_; LogVarSet ipgLogVars_; LogVarSet posCountedLvs_; LogVarSet negCountedLvs_; @@ -148,14 +145,14 @@ typedef vector Clauses; -class LiteralLvTypes +class LitLvTypes { public: - struct CompareLiteralLvTypes + struct CompareLitLvTypes { bool operator() ( - const LiteralLvTypes& types1, - const LiteralLvTypes& types2) const + const LitLvTypes& types1, + const LitLvTypes& types2) const { if (types1.lid_ < types2.lid_) { return true; @@ -164,7 +161,7 @@ class LiteralLvTypes } }; - LiteralLvTypes (LiteralId lid, const LogVarTypes& lvTypes) : + LitLvTypes (LiteralId lid, const LogVarTypes& lvTypes) : lid_(lid), lvTypes_(lvTypes) { } LiteralId lid (void) const { return lid_; } @@ -172,14 +169,14 @@ class LiteralLvTypes const LogVarTypes& logVarTypes (void) const { return lvTypes_; } void setAllFullLogVars (void) { - lvTypes_ = LogVarTypes (lvTypes_.size(), LogVarType::FULL_LV); } + std::fill (lvTypes_.begin(), lvTypes_.end(), LogVarType::FULL_LV); } private: LiteralId lid_; LogVarTypes lvTypes_; }; -typedef TinySet LitLvTypesSet; +typedef TinySet LitLvTypesSet; @@ -192,21 +189,11 @@ class LiftedWCNF const Clauses& clauses (void) const { return clauses_; } - double posWeight (LiteralId lid) const - { - unordered_map>::const_iterator it; - it = weights_.find (lid); - return it != weights_.end() ? it->second.first : 1.0; - } + double posWeight (LiteralId lid) const; - double negWeight (LiteralId lid) const - { - unordered_map>::const_iterator it; - it = weights_.find (lid); - return it != weights_.end() ? it->second.second : 1.0; - } + double negWeight (LiteralId lid) const; - Clause createClauseForLiteral (LiteralId lid) const; + Clause createClause (LiteralId lid) const; void printFormulaIndicators (void) const; @@ -216,30 +203,19 @@ class LiftedWCNF private: - LiteralId getLiteralId (PrvGroup prvGroup, unsigned range) - { - assert (Util::contains (map_, prvGroup)); - return map_[prvGroup][range]; - } + LiteralId getLiteralId (PrvGroup prvGroup, unsigned range); - void addWeight (LiteralId lid, double posW, double negW) - { - weights_[lid] = make_pair (posW, negW); - } + void addWeight (LiteralId lid, double posW, double negW); void addIndicatorClauses (const ParfactorList& pfList); void addParameterClauses (const ParfactorList& pfList); - Clauses clauses_; - - unordered_map> map_; - - unordered_map> weights_; - - const ParfactorList& pfList_; - - LiteralId freeLiteralId_; + Clauses clauses_; + LiteralId freeLiteralId_; + const ParfactorList& pfList_; + unordered_map> map_; + unordered_map> weights_; }; #endif // HORUS_LIFTEDWCNF_H From 278f8f77f5adc3587b0e4cafd090a26a18948635 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Wed, 7 Nov 2012 18:42:11 +0000 Subject: [PATCH 32/52] Improve independence --- packages/CLPBN/horus/LiftedCircuit.cpp | 69 ++++++++++++++++---------- packages/CLPBN/horus/LiftedCircuit.h | 3 ++ 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index 43036626a..1166f1e9d 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -251,31 +251,31 @@ LiftedCircuit::compile ( 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; } - + if (tryGrounding (follow, clauses)) { return; } - + // assert (false); *follow = new CompilationFailedNode (clauses); } @@ -335,29 +335,26 @@ LiftedCircuit::tryIndependence ( if (clauses.size() == 1) { return false; } - // TODO compare all subsets with all subsets - for (size_t i = 0; i < clauses.size(); i++) { - bool indep = true; - TinySet lids1 = clauses[i].lidSet(); - for (size_t j = 0; j < clauses.size(); j++) { - TinySet lids2 = clauses[j].lidSet(); - if (i != j && ((lids1 & lids2).empty() == false)) { - indep = false; + 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 (isIndependentClause (indepClauses[i], depClauses) == false) { + depClauses.push_back (indepClauses[i]); + indepClauses.erase (indepClauses.begin() + i); + finish = false; break; } } - if (indep == true) { - Clauses newClauses = clauses; - newClauses.erase (newClauses.begin() + i); - stringstream explanation; - explanation << " Independence on clause Nº " << i ; - AndNode* andNode = new AndNode (clauses, explanation.str()); - Clauses indepClause = {clauses[i]}; - compile (andNode->leftBranch(), indepClause); - compile (andNode->rightBranch(), newClauses); - (*follow) = andNode; - return true; - } + } + if (indepClauses.empty() == false) { + AndNode* andNode = new AndNode (clauses, " Independence"); + compile (andNode->leftBranch(), depClauses); + compile (andNode->rightBranch(), indepClauses); + (*follow) = andNode; + return true; } return false; } @@ -653,6 +650,24 @@ LiftedCircuit::shatterCountedLogVarsAux ( +bool +LiftedCircuit::isIndependentClause ( + Clause& clause, + Clauses& otherClauses) const +{ + // TODO consider counted log vars + TinySet lidSet = clause.lidSet(); + for (size_t i = 0; i < otherClauses.size(); i++) { + if ((lidSet & otherClauses[i].lidSet()).empty() == false) { + return false; + } + } + return true; +} + + + + LitLvTypesSet LiftedCircuit::smoothCircuit (CircuitNode* node) { diff --git a/packages/CLPBN/horus/LiftedCircuit.h b/packages/CLPBN/horus/LiftedCircuit.h index d5f1556f1..e0adf49f5 100644 --- a/packages/CLPBN/horus/LiftedCircuit.h +++ b/packages/CLPBN/horus/LiftedCircuit.h @@ -52,6 +52,7 @@ class OrNode : public CircuitNode CircuitNode** rightBranch (void) { return &rightBranch_; } double weight (void) const; + private: CircuitNode* leftBranch_; CircuitNode* rightBranch_; @@ -241,6 +242,8 @@ class LiftedCircuit bool shatterCountedLogVarsAux (Clauses& clauses); bool shatterCountedLogVarsAux (Clauses& clauses, size_t idx1, size_t idx2); + + bool isIndependentClause (Clause& clause, Clauses& otherClauses) const; LitLvTypesSet smoothCircuit (CircuitNode* node); From d2ae171bb5ab422f2752eabd972b25a35a3af021 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Wed, 7 Nov 2012 18:43:13 +0000 Subject: [PATCH 33/52] Improve Clause constructor --- packages/CLPBN/horus/LiftedWCNF.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/CLPBN/horus/LiftedWCNF.h b/packages/CLPBN/horus/LiftedWCNF.h index f56b2c090..5eb679168 100644 --- a/packages/CLPBN/horus/LiftedWCNF.h +++ b/packages/CLPBN/horus/LiftedWCNF.h @@ -67,7 +67,7 @@ typedef vector Literals; class Clause { public: - Clause (const ConstraintTree& ct) : constr_(ct) { } + Clause (const ConstraintTree& ct = ConstraintTree({})) : constr_(ct) { } Clause (vector> names) : constr_(ConstraintTree (names)) { } From 6db4d37684f835f673814d0e87290b3f7a118f8d Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Wed, 7 Nov 2012 21:21:42 +0000 Subject: [PATCH 34/52] Independence: consider also counted log vars --- packages/CLPBN/horus/LiftedCircuit.cpp | 5 +- packages/CLPBN/horus/LiftedWCNF.cpp | 73 +++++++++++++++++++------- packages/CLPBN/horus/LiftedWCNF.h | 2 + 3 files changed, 56 insertions(+), 24 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index 1166f1e9d..d520a51a5 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -655,10 +655,8 @@ LiftedCircuit::isIndependentClause ( Clause& clause, Clauses& otherClauses) const { - // TODO consider counted log vars - TinySet lidSet = clause.lidSet(); for (size_t i = 0; i < otherClauses.size(); i++) { - if ((lidSet & otherClauses[i].lidSet()).empty() == false) { + if (Clause::independentClauses (clause, otherClauses[i]) == false) { return false; } } @@ -667,7 +665,6 @@ LiftedCircuit::isIndependentClause ( - LitLvTypesSet LiftedCircuit::smoothCircuit (CircuitNode* node) { diff --git a/packages/CLPBN/horus/LiftedWCNF.cpp b/packages/CLPBN/horus/LiftedWCNF.cpp index 6585947de..f9f47d155 100644 --- a/packages/CLPBN/horus/LiftedWCNF.cpp +++ b/packages/CLPBN/horus/LiftedWCNF.cpp @@ -288,6 +288,24 @@ Clause::removeLiteral (size_t 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; +} + + + void Clause::printClauses (const Clauses& clauses) { @@ -335,27 +353,11 @@ LiftedWCNF::LiftedWCNF (const ParfactorList& pfList) //addIndicatorClauses (pfList); //addParameterClauses (pfList); + /* vector> names = { -/* - {"p1","p1"}, - {"p1","p2"}, - {"p2","p1"}, - {"p2","p2"}, - {"p1","p3"}, - {"p2","p3"}, - {"p3","p3"}, - {"p3","p2"}, - {"p3","p1"} -*/ - {"p1","p1"}, - {"p1","p2"}, - {"p1","p3"}, - {"p2","p1"}, - {"p2","p2"}, - {"p2","p3"}, - {"p3","p1"}, - {"p3","p2"}, - {"p3","p3"} + {"p1","p1"},{"p1","p2"},{"p1","p3"}, + {"p2","p1"},{"p2","p2"},{"p2","p3"}, + {"p3","p1"},{"p3","p2"},{"p3","p3"} }; Clause c1 (names); @@ -372,6 +374,37 @@ LiftedWCNF::LiftedWCNF (const ParfactorList& pfList) addWeight (1, 2.0, 5.0); freeLiteralId_ = 2; + */ + + Literal lit1 (0, {0}); + Literal lit2 (1, {}); + Literal lit3 (2, {}); + Literal lit4 (3, {}); + + vector> names = {{"p1"},{"p2"}}; + Clause c1 (names); + c1.addLiteral (lit1); + c1.addLiteral (lit2); + c1.addPosCountedLogVar (0); + clauses_.push_back (c1); + + Clause c2 (names); + c2.addLiteral (lit1); + c2.addLiteral (lit3); + c2.addNegCountedLogVar (0); + clauses_.push_back (c2); + /* + Clause c3; + c3.addLiteral (lit3); + c3.addLiteral (lit4); + clauses_.push_back (c3); + + Clause c4; + c4.addLiteral (lit4); + c4.addLiteral (lit3); + clauses_.push_back (c4); + */ + freeLiteralId_ = 4; cout << "FORMULA INDICATORS:" << endl; // printFormulaIndicators(); diff --git a/packages/CLPBN/horus/LiftedWCNF.h b/packages/CLPBN/horus/LiftedWCNF.h index 5eb679168..fd236a80d 100644 --- a/packages/CLPBN/horus/LiftedWCNF.h +++ b/packages/CLPBN/horus/LiftedWCNF.h @@ -126,6 +126,8 @@ class Clause LogVarTypes logVarTypes (size_t litIdx) const; void removeLiteral (size_t litIdx); + + static bool independentClauses (Clause& c1, Clause& c2); static void printClauses (const vector& clauses); From f7db522c6c6ba7caba4918a3b5b4cf3963a08002 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Wed, 7 Nov 2012 23:45:43 +0000 Subject: [PATCH 35/52] InxExc: improve the code --- packages/CLPBN/horus/LiftedCircuit.cpp | 123 ++++++++++++++++--------- packages/CLPBN/horus/LiftedCircuit.h | 26 +++--- packages/CLPBN/horus/LiftedWCNF.cpp | 14 +-- 3 files changed, 100 insertions(+), 63 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index d520a51a5..cb7ba75a4 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -341,7 +341,7 @@ LiftedCircuit::tryIndependence ( while (finish == false) { finish = true; for (size_t i = 0; i < indepClauses.size(); i++) { - if (isIndependentClause (indepClauses[i], depClauses) == false) { + if (independentClause (indepClauses[i], depClauses) == false) { depClauses.push_back (indepClauses[i]); indepClauses.erase (indepClauses.begin() + i); finish = false; @@ -402,44 +402,58 @@ LiftedCircuit::tryInclusionExclusion ( CircuitNode** follow, Clauses& clauses) { - // TODO compare all subsets with all subsets for (size_t i = 0; i < clauses.size(); i++) { - const Literals& literals = clauses[i].literals(); - for (size_t j = 0; j < literals.size(); j++) { - bool indep = true; - for (size_t k = 0; k < literals.size(); k++) { - LogVarSet intersect = literals[j].logVarSet() - & literals[k].logVarSet(); - if (j != k && intersect.empty() == false) { - indep = false; + 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 (indep) { - // TODO this should be have to be count normalized too - ConstraintTree really = clauses[i].constr(); - Clause c1 (really.projectedCopy ( - literals[j].logVars())); - c1.addLiteral (literals[j]); - Clause c2 = clauses[i]; - c2.removeLiteral (j); - Clauses plus1Clauses = clauses; - Clauses plus2Clauses = clauses; - Clauses minusClauses = clauses; - plus1Clauses.erase (plus1Clauses.begin() + i); - plus2Clauses.erase (plus2Clauses.begin() + i); - minusClauses.erase (minusClauses.begin() + i); - plus1Clauses.push_back (c1); - plus2Clauses.push_back (c2); - minusClauses.push_back (c1); - minusClauses.push_back (c2); - IncExcNode* ieNode = new IncExcNode (clauses); - compile (ieNode->plus1Branch(), plus1Clauses); - compile (ieNode->plus2Branch(), plus2Clauses); - compile (ieNode->minusBranch(), minusClauses); - *follow = ieNode; - return true; + } + if (indepLits.empty() == false) { + // TODO this should be have to be count normalized too + LogVarSet lvs1; + for (size_t j = 0; j < depLits.size(); j++) { + lvs1 |= depLits[j].logVarSet(); } + LogVarSet lvs2; + for (size_t j = 0; j < indepLits.size(); j++) { + lvs2 |= indepLits[j].logVarSet(); + } + Clause c1 (clauses[i].constr().projectedCopy (lvs1)); + for (size_t j = 0; j < depLits.size(); j++) { + c1.addLiteral (depLits[j]); + } + Clause c2 (clauses[i].constr().projectedCopy (lvs2)); + for (size_t j = 0; j < indepLits.size(); j++) { + c2.addLiteral (indepLits[j]); + } + Clauses plus1Clauses = clauses; + Clauses plus2Clauses = clauses; + Clauses minusClauses = clauses; + plus1Clauses.erase (plus1Clauses.begin() + i); + plus2Clauses.erase (plus2Clauses.begin() + i); + minusClauses.erase (minusClauses.begin() + i); + plus1Clauses.push_back (c1); + plus2Clauses.push_back (c2); + minusClauses.push_back (c1); + minusClauses.push_back (c2); + stringstream explanation; + explanation << " IncExc on clause nº " << i + 1; + IncExcNode* ieNode = new IncExcNode (clauses, explanation.str()); + compile (ieNode->plus1Branch(), plus1Clauses); + compile (ieNode->plus2Branch(), plus2Clauses); + compile (ieNode->minusBranch(), minusClauses); + *follow = ieNode; + return true; } } return false; @@ -651,7 +665,7 @@ LiftedCircuit::shatterCountedLogVarsAux ( bool -LiftedCircuit::isIndependentClause ( +LiftedCircuit::independentClause ( Clause& clause, Clauses& otherClauses) const { @@ -665,6 +679,22 @@ LiftedCircuit::isIndependentClause ( +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) { @@ -882,7 +912,7 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) ss << "n" << nrAuxNodes; string auxNode = ss.str(); nrAuxNodes ++; - + string opStyle = "shape=circle,width=0.7,margin=\"0.0,0.0\"," ; switch (getCircuitNodeType (node)) { @@ -890,7 +920,7 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) OrNode* casted = dynamic_cast(node); printClauses (casted, os); - os << auxNode << " [label=\"∨\"]" << endl; + os << auxNode << " [" << opStyle << "label=\"∨\"]" << endl; os << escapeNode (node) << " -> " << auxNode; os << " [label=\"" << node->explanation() << "\"]" ; os << endl; @@ -914,7 +944,7 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) AndNode* casted = dynamic_cast(node); printClauses (casted, os); - os << auxNode << " [label=\"∧\"]" << endl; + os << auxNode << " [" << opStyle << "label=\"∧\"]" << endl; os << escapeNode (node) << " -> " << auxNode; os << " [label=\"" << node->explanation() << "\"]" ; os << endl; @@ -938,7 +968,7 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) SetOrNode* casted = dynamic_cast(node); printClauses (casted, os); - os << auxNode << " [label=\"∨(X)\"]" << endl; + os << auxNode << " [" << opStyle << "label=\"∨(X)\"]" << endl; os << escapeNode (node) << " -> " << auxNode; os << " [label=\"" << node->explanation() << "\"]" ; os << endl; @@ -956,7 +986,7 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) SetAndNode* casted = dynamic_cast(node); printClauses (casted, os); - os << auxNode << " [label=\"∧(X)\"]" << endl; + os << auxNode << " [" << opStyle << "label=\"∧(X)\"]" << endl; os << escapeNode (node) << " -> " << auxNode; os << " [label=\"" << node->explanation() << "\"]" ; os << endl; @@ -974,7 +1004,8 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) IncExcNode* casted = dynamic_cast(node); printClauses (casted, os); - os << auxNode << " [label=\"IncExc\"]" << endl; + os << auxNode << " [" << opStyle << "label=\"+ - +\"]" ; + os << endl; os << escapeNode (node) << " -> " << auxNode; os << " [label=\"" << node->explanation() << "\"]" ; os << endl; @@ -983,17 +1014,17 @@ LiftedCircuit::exportToGraphViz (CircuitNode* node, ofstream& os) 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; - os << auxNode << " -> " ; - os << escapeNode (*casted->minusBranch()) << endl; - os << " [label=\" " << (*casted->minusBranch())->weight() << "\"]" ; - os << endl; - exportToGraphViz (*casted->plus1Branch(), os); exportToGraphViz (*casted->plus2Branch(), os); exportToGraphViz (*casted->minusBranch(), os); diff --git a/packages/CLPBN/horus/LiftedCircuit.h b/packages/CLPBN/horus/LiftedCircuit.h index e0adf49f5..073de64fe 100644 --- a/packages/CLPBN/horus/LiftedCircuit.h +++ b/packages/CLPBN/horus/LiftedCircuit.h @@ -54,8 +54,8 @@ class OrNode : public CircuitNode double weight (void) const; private: - CircuitNode* leftBranch_; - CircuitNode* rightBranch_; + CircuitNode* leftBranch_; + CircuitNode* rightBranch_; }; @@ -88,8 +88,8 @@ class AndNode : public CircuitNode double weight (void) const; private: - CircuitNode* leftBranch_; - CircuitNode* rightBranch_; + CircuitNode* leftBranch_; + CircuitNode* rightBranch_; }; @@ -139,8 +139,8 @@ class SetAndNode : public CircuitNode class IncExcNode : public CircuitNode { public: - IncExcNode (const Clauses& clauses) - : CircuitNode (clauses), plus1Branch_(0), + IncExcNode (const Clauses& clauses, string explanation) + : CircuitNode (clauses, explanation), plus1Branch_(0), plus2Branch_(0), minusBranch_(0) { } CircuitNode** plus1Branch (void) { return &plus1Branch_; } @@ -150,9 +150,9 @@ class IncExcNode : public CircuitNode double weight (void) const; private: - CircuitNode* plus1Branch_; - CircuitNode* plus2Branch_; - CircuitNode* minusBranch_; + CircuitNode* plus1Branch_; + CircuitNode* plus2Branch_; + CircuitNode* minusBranch_; }; @@ -198,7 +198,8 @@ class TrueNode : public CircuitNode class CompilationFailedNode : public CircuitNode { public: - CompilationFailedNode (const Clauses& clauses) : CircuitNode (clauses) { } + CompilationFailedNode (const Clauses& clauses) + : CircuitNode (clauses) { } double weight (void) const; }; @@ -243,7 +244,10 @@ class LiftedCircuit bool shatterCountedLogVarsAux (Clauses& clauses, size_t idx1, size_t idx2); - bool isIndependentClause (Clause& clause, Clauses& otherClauses) const; + bool independentClause (Clause& clause, Clauses& otherClauses) const; + + bool independentLiteral (const Literal& lit, + const Literals& otherLits) const; LitLvTypesSet smoothCircuit (CircuitNode* node); diff --git a/packages/CLPBN/horus/LiftedWCNF.cpp b/packages/CLPBN/horus/LiftedWCNF.cpp index f9f47d155..11e8b992b 100644 --- a/packages/CLPBN/horus/LiftedWCNF.cpp +++ b/packages/CLPBN/horus/LiftedWCNF.cpp @@ -377,22 +377,24 @@ LiftedWCNF::LiftedWCNF (const ParfactorList& pfList) */ Literal lit1 (0, {0}); - Literal lit2 (1, {}); - Literal lit3 (2, {}); - Literal lit4 (3, {}); + Literal lit2 (1, {0}); + Literal lit3 (2, {1}); + Literal lit4 (3, {1}); - vector> names = {{"p1"},{"p2"}}; + vector> names = {{"p1","p2"},{"p3","p4"}}; Clause c1 (names); c1.addLiteral (lit1); c1.addLiteral (lit2); - c1.addPosCountedLogVar (0); + c1.addLiteral (lit3); + c1.addLiteral (lit4); + //c1.addPosCountedLogVar (0); clauses_.push_back (c1); Clause c2 (names); c2.addLiteral (lit1); c2.addLiteral (lit3); c2.addNegCountedLogVar (0); - clauses_.push_back (c2); + //clauses_.push_back (c2); /* Clause c3; c3.addLiteral (lit3); From a8c4f4fc52264aaf9bf76c22ef963179d21bf043 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Thu, 8 Nov 2012 14:02:18 +0000 Subject: [PATCH 36/52] fix one more TODO --- packages/CLPBN/horus/LiftedWCNF.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/CLPBN/horus/LiftedWCNF.cpp b/packages/CLPBN/horus/LiftedWCNF.cpp index 11e8b992b..139fb6a43 100644 --- a/packages/CLPBN/horus/LiftedWCNF.cpp +++ b/packages/CLPBN/horus/LiftedWCNF.cpp @@ -279,10 +279,12 @@ Clause::logVarTypes (size_t litIdx) const void Clause::removeLiteral (size_t litIdx) { - // TODO maybe we need to clean up pos/neg/ipg lvs too - LogVarSet lvs (literals_[litIdx].logVars()); - lvs -= getLogVarSetExcluding (litIdx); - constr_.remove (lvs); + LogVarSet lvsToRemove = literals_[litIdx].logVarSet() + - getLogVarSetExcluding (litIdx); + ipgLogVars_ -= lvsToRemove; + posCountedLvs_ -= lvsToRemove; + negCountedLvs_ -= lvsToRemove; + constr_.remove (lvsToRemove); literals_.erase (literals_.begin() + litIdx); } From 0ed89d3eebf2bb7730bc0465c1cb0f94cf7cf07d Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Thu, 8 Nov 2012 15:05:48 +0000 Subject: [PATCH 37/52] add flag to lifted knowledge compilation and s/fove/lve --- packages/CLPBN/README.txt | 3 ++- .../CLPBN/benchmarks/city/{fove_tests.sh => lve_tests.sh} | 4 ++-- .../comp_workshops/{fove_tests.sh => lve_tests.sh} | 4 ++-- packages/CLPBN/benchmarks/run_all.sh | 8 ++++---- .../benchmarks/smokers/{fove_tests.sh => lve_tests.sh} | 4 ++-- .../smokers_evidence/{fove_tests.sh => lve_tests.sh} | 4 ++-- .../workshop_attrs/{fove_tests.sh => lve_tests.sh} | 4 ++-- packages/CLPBN/clpbn/horus.yap | 3 ++- packages/CLPBN/examples/School/school_32.yap | 2 +- packages/CLPBN/examples/burglary-alarm.pfl | 2 +- packages/CLPBN/examples/city.yap | 2 +- packages/CLPBN/examples/comp_workshops.yap | 2 +- packages/CLPBN/examples/fail1.yap | 2 +- packages/CLPBN/examples/fail2.yap | 2 +- packages/CLPBN/examples/social_domain1.yap | 2 +- packages/CLPBN/examples/social_domain2.yap | 2 +- packages/CLPBN/examples/workshop_attrs.yap | 2 +- packages/CLPBN/horus/Horus.h | 5 +++-- packages/CLPBN/horus/LiftedVe.cpp | 2 +- packages/CLPBN/horus/LiftedWCNF.cpp | 8 ++++---- packages/CLPBN/horus/LiftedWCNF.h | 6 +++--- packages/CLPBN/horus/Util.cpp | 8 +++++--- 22 files changed, 43 insertions(+), 38 deletions(-) rename packages/CLPBN/benchmarks/city/{fove_tests.sh => lve_tests.sh} (91%) rename packages/CLPBN/benchmarks/comp_workshops/{fove_tests.sh => lve_tests.sh} (90%) rename packages/CLPBN/benchmarks/smokers/{fove_tests.sh => lve_tests.sh} (87%) rename packages/CLPBN/benchmarks/smokers_evidence/{fove_tests.sh => lve_tests.sh} (89%) rename packages/CLPBN/benchmarks/workshop_attrs/{fove_tests.sh => lve_tests.sh} (92%) diff --git a/packages/CLPBN/README.txt b/packages/CLPBN/README.txt index c24eccd39..76231b268 100644 --- a/packages/CLPBN/README.txt +++ b/packages/CLPBN/README.txt @@ -49,11 +49,12 @@ Inference Options PFL supports both ground and lifted inference. The inference algorithm can be chosen using the set_solver/1 predicate. The following algorithms are supported: -- fove: lifted variable elimination with arbitrary constraints (GC-FOVE) +- lve: generalized counting first-order variable elimination (GC-FOVE) - hve: (ground) variable elimination - lbp: lifted first-order belief propagation - cbp: counting belief propagation - bp: (ground) belief propagation +- lkc: lifted first-order knowledge compilation For example, if we want to use ground variable elimination to solve some query, we need to call first the following goal: diff --git a/packages/CLPBN/benchmarks/city/fove_tests.sh b/packages/CLPBN/benchmarks/city/lve_tests.sh similarity index 91% rename from packages/CLPBN/benchmarks/city/fove_tests.sh rename to packages/CLPBN/benchmarks/city/lve_tests.sh index 149d3b332..edb79f6c4 100755 --- a/packages/CLPBN/benchmarks/city/fove_tests.sh +++ b/packages/CLPBN/benchmarks/city/lve_tests.sh @@ -3,7 +3,7 @@ source city.sh source ../benchs.sh -SOLVER="fove" +SOLVER="lve" function run_all_graphs { @@ -32,5 +32,5 @@ function run_all_graphs } prepare_new_run -run_all_graphs "fove " +run_all_graphs "lve " diff --git a/packages/CLPBN/benchmarks/comp_workshops/fove_tests.sh b/packages/CLPBN/benchmarks/comp_workshops/lve_tests.sh similarity index 90% rename from packages/CLPBN/benchmarks/comp_workshops/fove_tests.sh rename to packages/CLPBN/benchmarks/comp_workshops/lve_tests.sh index 68e0c8d07..89d607b07 100755 --- a/packages/CLPBN/benchmarks/comp_workshops/fove_tests.sh +++ b/packages/CLPBN/benchmarks/comp_workshops/lve_tests.sh @@ -3,7 +3,7 @@ source cw.sh source ../benchs.sh -SOLVER="fove" +SOLVER="lve" function run_all_graphs { @@ -26,6 +26,6 @@ function run_all_graphs } prepare_new_run -run_all_graphs "fove " +run_all_graphs "lve " diff --git a/packages/CLPBN/benchmarks/run_all.sh b/packages/CLPBN/benchmarks/run_all.sh index bf2571256..4962fd7e5 100755 --- a/packages/CLPBN/benchmarks/run_all.sh +++ b/packages/CLPBN/benchmarks/run_all.sh @@ -3,7 +3,7 @@ cd workshop_attrs source hve_tests.sh source bp_tests.sh -source fove_tests.sh +source lve_tests.sh source lbp_tests.sh source cbp_tests.sh cd .. @@ -11,7 +11,7 @@ cd .. cd comp_workshops source hve_tests.sh source bp_tests.sh -source fove_tests.sh +source lve_tests.sh source lbp_tests.sh source cbp_tests.sh cd .. @@ -19,7 +19,7 @@ cd .. cd city source hve_tests.sh source bp_tests.sh -source fove_tests.sh +source lve_tests.sh source lbp_tests.sh source cbp_tests.sh cd .. @@ -27,7 +27,7 @@ cd .. cd smokers source hve_tests.sh source bp_tests.sh -source fove_tests.sh +source lve_tests.sh source lbp_tests.sh source cbp_tests.sh cd .. diff --git a/packages/CLPBN/benchmarks/smokers/fove_tests.sh b/packages/CLPBN/benchmarks/smokers/lve_tests.sh similarity index 87% rename from packages/CLPBN/benchmarks/smokers/fove_tests.sh rename to packages/CLPBN/benchmarks/smokers/lve_tests.sh index d36f9fd46..e7e08c253 100755 --- a/packages/CLPBN/benchmarks/smokers/fove_tests.sh +++ b/packages/CLPBN/benchmarks/smokers/lve_tests.sh @@ -3,7 +3,7 @@ source sm.sh source ../benchs.sh -SOLVER="fove" +SOLVER="lve" function run_all_graphs { @@ -26,6 +26,6 @@ function run_all_graphs } prepare_new_run -run_all_graphs "fove " +run_all_graphs "lve " diff --git a/packages/CLPBN/benchmarks/smokers_evidence/fove_tests.sh b/packages/CLPBN/benchmarks/smokers_evidence/lve_tests.sh similarity index 89% rename from packages/CLPBN/benchmarks/smokers_evidence/fove_tests.sh rename to packages/CLPBN/benchmarks/smokers_evidence/lve_tests.sh index 09e346839..5f32c8c6d 100755 --- a/packages/CLPBN/benchmarks/smokers_evidence/fove_tests.sh +++ b/packages/CLPBN/benchmarks/smokers_evidence/lve_tests.sh @@ -3,7 +3,7 @@ source sm.sh source ../benchs.sh -SOLVER="fove" +SOLVER="lve" function run_all_graphs { @@ -30,6 +30,6 @@ function run_all_graphs } prepare_new_run -run_all_graphs "fove " +run_all_graphs "lve " diff --git a/packages/CLPBN/benchmarks/workshop_attrs/fove_tests.sh b/packages/CLPBN/benchmarks/workshop_attrs/lve_tests.sh similarity index 92% rename from packages/CLPBN/benchmarks/workshop_attrs/fove_tests.sh rename to packages/CLPBN/benchmarks/workshop_attrs/lve_tests.sh index 2edc90919..10c9e5e1e 100755 --- a/packages/CLPBN/benchmarks/workshop_attrs/fove_tests.sh +++ b/packages/CLPBN/benchmarks/workshop_attrs/lve_tests.sh @@ -3,7 +3,7 @@ source wa.sh source ../benchs.sh -SOLVER="fove" +SOLVER="lve" function run_all_graphs { @@ -32,6 +32,6 @@ function run_all_graphs } prepare_new_run -run_all_graphs "fove " +run_all_graphs "lve " diff --git a/packages/CLPBN/clpbn/horus.yap b/packages/CLPBN/clpbn/horus.yap index c557a4c66..6bed62fa2 100644 --- a/packages/CLPBN/clpbn/horus.yap +++ b/packages/CLPBN/clpbn/horus.yap @@ -39,8 +39,9 @@ set_solver(ve) :- !, set_clpbn_flag(solver,ve). set_solver(bdd) :- !, set_clpbn_flag(solver,bdd). set_solver(jt) :- !, set_clpbn_flag(solver,jt). set_solver(gibbs) :- !, set_clpbn_flag(solver,gibbs). -set_solver(fove) :- !, set_clpbn_flag(solver,fove), set_horus_flag(lifted_solver, fove). +set_solver(lve) :- !, set_clpbn_flag(solver,fove), set_horus_flag(lifted_solver, lve). set_solver(lbp) :- !, set_clpbn_flag(solver,fove), set_horus_flag(lifted_solver, lbp). +set_solver(lkc) :- !, set_clpbn_flag(solver,fove), set_horus_flag(lifted_solver, lkc). set_solver(hve) :- !, set_clpbn_flag(solver,bp), set_horus_flag(ground_solver, ve). set_solver(bp) :- !, set_clpbn_flag(solver,bp), set_horus_flag(ground_solver, bp). set_solver(cbp) :- !, set_clpbn_flag(solver,bp), set_horus_flag(ground_solver, cbp). diff --git a/packages/CLPBN/examples/School/school_32.yap b/packages/CLPBN/examples/School/school_32.yap index 3ba7f855a..00dc27a2c 100644 --- a/packages/CLPBN/examples/School/school_32.yap +++ b/packages/CLPBN/examples/School/school_32.yap @@ -18,7 +18,7 @@ total_students(256). :- ensure_loaded(parschema). :- yap_flag(unknown,error). -%:- clpbn_horus:set_solver(fove). +%:- clpbn_horus:set_solver(lve). %:- clpbn_horus:set_solver(hve). :- clpbn_horus:set_solver(bp). %:- clpbn_horus:set_solver(bdd). diff --git a/packages/CLPBN/examples/burglary-alarm.pfl b/packages/CLPBN/examples/burglary-alarm.pfl index 40a0c926b..defbf83da 100644 --- a/packages/CLPBN/examples/burglary-alarm.pfl +++ b/packages/CLPBN/examples/burglary-alarm.pfl @@ -1,6 +1,6 @@ :- use_module(library(pfl)). -%:- set_solver(fove). +%:- set_solver(lve). %:- set_solver(hve). %:- set_solver(bp). %:- set_solver(cbp). diff --git a/packages/CLPBN/examples/city.yap b/packages/CLPBN/examples/city.yap index 5cad29586..3647698cc 100644 --- a/packages/CLPBN/examples/city.yap +++ b/packages/CLPBN/examples/city.yap @@ -1,6 +1,6 @@ :- use_module(library(pfl)). -%:- set_solver(fove). +%:- set_solver(lve). %:- set_solver(hve). %:- set_solver(bp). %:- set_solver(cbp). diff --git a/packages/CLPBN/examples/comp_workshops.yap b/packages/CLPBN/examples/comp_workshops.yap index 39a14d8bd..2ab7d2cd5 100644 --- a/packages/CLPBN/examples/comp_workshops.yap +++ b/packages/CLPBN/examples/comp_workshops.yap @@ -1,6 +1,6 @@ :- use_module(library(pfl)). -%:- set_solver(fove). +%:- set_solver(lve). %:- set_solver(hve). %:- set_solver(bp). %:- set_solver(cbp). diff --git a/packages/CLPBN/examples/fail1.yap b/packages/CLPBN/examples/fail1.yap index aa5cfc5db..1646fd8ff 100644 --- a/packages/CLPBN/examples/fail1.yap +++ b/packages/CLPBN/examples/fail1.yap @@ -1,7 +1,7 @@ :- use_module(library(pfl)). -:- set_pfl_flag(solver,fove). +:- set_pfl_flag(solver,lve). %:- set_pfl_flag(solver,bp), clpbn_horus:set_horus_flag(inf_alg,ve). %:- set_pfl_flag(solver,bp), clpbn_horus:set_horus_flag(inf_alg,bp). %:- set_pfl_flag(solver,bp), clpbn_horus:set_horus_flag(inf_alg,cbp). diff --git a/packages/CLPBN/examples/fail2.yap b/packages/CLPBN/examples/fail2.yap index 7e62ea42c..342cc9c52 100644 --- a/packages/CLPBN/examples/fail2.yap +++ b/packages/CLPBN/examples/fail2.yap @@ -1,6 +1,6 @@ :- use_module(library(pfl)). -:- set_solver(fove). +:- set_solver(lve). %:- set_solver(hve). %:- set_solver(bp). %:- set_solver(cbp). diff --git a/packages/CLPBN/examples/social_domain1.yap b/packages/CLPBN/examples/social_domain1.yap index ba5b095d1..348ac4bec 100644 --- a/packages/CLPBN/examples/social_domain1.yap +++ b/packages/CLPBN/examples/social_domain1.yap @@ -1,6 +1,6 @@ :- use_module(library(pfl)). -%:- set_solver(fove). +%:- set_solver(lve). %:- set_solver(hve). %:- set_solver(bp). %:- set_solver(cbp). diff --git a/packages/CLPBN/examples/social_domain2.yap b/packages/CLPBN/examples/social_domain2.yap index af0327e8f..e02c2d9a1 100644 --- a/packages/CLPBN/examples/social_domain2.yap +++ b/packages/CLPBN/examples/social_domain2.yap @@ -1,6 +1,6 @@ :- use_module(library(pfl)). -%:- set_solver(fove). +%:- set_solver(lve). %:- set_solver(hve). %:- set_solver(bp). %:- set_solver(cbp). diff --git a/packages/CLPBN/examples/workshop_attrs.yap b/packages/CLPBN/examples/workshop_attrs.yap index 880adcae5..05a97106f 100644 --- a/packages/CLPBN/examples/workshop_attrs.yap +++ b/packages/CLPBN/examples/workshop_attrs.yap @@ -1,6 +1,6 @@ :- use_module(library(pfl)). -%:- set_solver(fove). +%:- set_solver(lve). %:- set_solver(hve). %:- set_solver(bp). %:- set_solver(cbp). diff --git a/packages/CLPBN/horus/Horus.h b/packages/CLPBN/horus/Horus.h index bb1d77bb9..2c8d20e1e 100644 --- a/packages/CLPBN/horus/Horus.h +++ b/packages/CLPBN/horus/Horus.h @@ -30,8 +30,9 @@ typedef unsigned long long ullong; enum LiftedSolver { - FOVE, // first order variable elimination - LBP, // lifted belief propagation + LVE, // generalized counting first-order variable elimination (GC-FOVE) + LBP, // lifted first-order belief propagation + LKC // lifted first-order knowledge compilation }; diff --git a/packages/CLPBN/horus/LiftedVe.cpp b/packages/CLPBN/horus/LiftedVe.cpp index 6ed2c22f7..2437906ce 100644 --- a/packages/CLPBN/horus/LiftedVe.cpp +++ b/packages/CLPBN/horus/LiftedVe.cpp @@ -647,7 +647,7 @@ void LiftedVe::printSolverFlags (void) const { stringstream ss; - ss << "fove [" ; + ss << "lve [" ; ss << "log_domain=" << Util::toString (Globals::logDomain); ss << "]" ; cout << ss.str() << endl; diff --git a/packages/CLPBN/horus/LiftedWCNF.cpp b/packages/CLPBN/horus/LiftedWCNF.cpp index 139fb6a43..31641187e 100644 --- a/packages/CLPBN/horus/LiftedWCNF.cpp +++ b/packages/CLPBN/horus/LiftedWCNF.cpp @@ -215,7 +215,7 @@ bool Clause::isIpgLogVar (LogVar X) const { assert (constr_.logVarSet().contains (X)); - return ipgLogVars_.contains (X); + return ipgLvs_.contains (X); } @@ -237,7 +237,7 @@ Clause::ipgCandidates (void) const { LogVarSet candidates; LogVarSet allLvs = constr_.logVarSet(); - allLvs -= ipgLogVars_; + allLvs -= ipgLvs_; allLvs -= posCountedLvs_; allLvs -= negCountedLvs_; for (size_t i = 0; i < allLvs.size(); i++) { @@ -281,7 +281,7 @@ Clause::removeLiteral (size_t litIdx) { LogVarSet lvsToRemove = literals_[litIdx].logVarSet() - getLogVarSetExcluding (litIdx); - ipgLogVars_ -= lvsToRemove; + ipgLvs_ -= lvsToRemove; posCountedLvs_ -= lvsToRemove; negCountedLvs_ -= lvsToRemove; constr_.remove (lvsToRemove); @@ -322,7 +322,7 @@ 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.ipgLogVars_, + os << clause.literals_[i].toString (clause.ipgLvs_, clause.posCountedLvs_, clause.negCountedLvs_); } if (clause.constr_.empty() == false) { diff --git a/packages/CLPBN/horus/LiftedWCNF.h b/packages/CLPBN/horus/LiftedWCNF.h index fd236a80d..263593cbf 100644 --- a/packages/CLPBN/horus/LiftedWCNF.h +++ b/packages/CLPBN/horus/LiftedWCNF.h @@ -81,9 +81,9 @@ class Clause bool isUnit (void) const { return literals_.size() == 1; } - LogVarSet ipgLogVars (void) const { return ipgLogVars_; } + LogVarSet ipgLogVars (void) const { return ipgLvs_; } - void addIpgLogVar (LogVar X) { ipgLogVars_.insert (X); } + void addIpgLogVar (LogVar X) { ipgLvs_.insert (X); } void addPosCountedLogVar (LogVar X) { posCountedLvs_.insert (X); } @@ -137,7 +137,7 @@ class Clause LogVarSet getLogVarSetExcluding (size_t idx) const; Literals literals_; - LogVarSet ipgLogVars_; + LogVarSet ipgLvs_; LogVarSet posCountedLvs_; LogVarSet negCountedLvs_; ConstraintTree constr_; diff --git a/packages/CLPBN/horus/Util.cpp b/packages/CLPBN/horus/Util.cpp index f7a785419..bef3414c6 100644 --- a/packages/CLPBN/horus/Util.cpp +++ b/packages/CLPBN/horus/Util.cpp @@ -13,7 +13,7 @@ bool logDomain = false; unsigned verbosity = 0; -LiftedSolver liftedSolver = LiftedSolver::FOVE; +LiftedSolver liftedSolver = LiftedSolver::LVE; GroundSolver groundSolver = GroundSolver::VE; @@ -210,10 +210,12 @@ setHorusFlag (string key, string value) ss << value; ss >> Globals::verbosity; } else if (key == "lifted_solver") { - if ( value == "fove") { - Globals::liftedSolver = LiftedSolver::FOVE; + if ( value == "lve") { + Globals::liftedSolver = LiftedSolver::LVE; } else if (value == "lbp") { Globals::liftedSolver = LiftedSolver::LBP; + } else if (value == "lkc") { + Globals::liftedSolver = LiftedSolver::LKC; } else { cerr << "warning: invalid value `" << value << "' " ; cerr << "for `" << key << "'" << endl; From 6a200760cab5410ee576f995bd7c5614fbaf6d43 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Thu, 8 Nov 2012 21:54:47 +0000 Subject: [PATCH 38/52] initial code to support calling a lifted knowledge compilation solver --- packages/CLPBN/horus/HorusYap.cpp | 13 ++++++++++- packages/CLPBN/horus/LiftedKc.cpp | 38 +++++++++++++++++++++++++++++++ packages/CLPBN/horus/LiftedKc.h | 28 +++++++++++++++++++++++ packages/CLPBN/horus/Makefile.in | 5 +++- 4 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 packages/CLPBN/horus/LiftedKc.cpp create mode 100644 packages/CLPBN/horus/LiftedKc.h diff --git a/packages/CLPBN/horus/HorusYap.cpp b/packages/CLPBN/horus/HorusYap.cpp index 138a86ccc..7246beb5e 100644 --- a/packages/CLPBN/horus/HorusYap.cpp +++ b/packages/CLPBN/horus/HorusYap.cpp @@ -14,6 +14,7 @@ #include "LiftedBp.h" #include "CountingBp.h" #include "BeliefProp.h" +#include "LiftedKc.h" #include "ElimGraph.h" #include "BayesBall.h" @@ -76,6 +77,7 @@ createLiftedNetwork (void) readLiftedEvidence (YAP_ARG2, *(obsFormulas)); LiftedNetwork* net = new LiftedNetwork (pfList, obsFormulas); + YAP_Int p = (YAP_Int) (net); return YAP_Unify (YAP_MkIntTerm (p), YAP_ARG3); } @@ -273,6 +275,8 @@ readParameters (YAP_Term paramL) int runLiftedSolver (void) { + // TODO one solver instatiation should be used + // to solve several inference tasks LiftedNetwork* network = (LiftedNetwork*) YAP_IntOfTerm (YAP_ARG1); YAP_Term taskList = YAP_ARG2; vector results; @@ -303,7 +307,7 @@ runLiftedSolver (void) } jointList = YAP_TailOfTerm (jointList); } - if (Globals::liftedSolver == LiftedSolver::FOVE) { + if (Globals::liftedSolver == LiftedSolver::LVE) { LiftedVe solver (pfListCopy); if (Globals::verbosity > 0 && taskList == YAP_ARG2) { solver.printSolverFlags(); @@ -317,6 +321,13 @@ runLiftedSolver (void) cout << endl; } results.push_back (solver.solveQuery (queryVars)); + } else if (Globals::liftedSolver == LiftedSolver::LKC) { + LiftedKc solver (pfListCopy); + if (Globals::verbosity > 0 && taskList == YAP_ARG2) { + solver.printSolverFlags(); + cout << endl; + } + results.push_back (solver.solveQuery (queryVars)); } else { assert (false); } diff --git a/packages/CLPBN/horus/LiftedKc.cpp b/packages/CLPBN/horus/LiftedKc.cpp new file mode 100644 index 000000000..7566a6d90 --- /dev/null +++ b/packages/CLPBN/horus/LiftedKc.cpp @@ -0,0 +1,38 @@ +#include "LiftedKc.h" +#include "LiftedWCNF.h" +#include "LiftedCircuit.h" + + +LiftedKc::LiftedKc (const ParfactorList& pfList) + : pfList_(pfList) +{ + lwcnf_ = new LiftedWCNF (pfList); + circuit_ = new LiftedCircuit (lwcnf_); +} + + + +LiftedKc::~LiftedKc (void) +{ +} + + + +Params +LiftedKc::solveQuery (const Grounds&) +{ + 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/horus/LiftedKc.h b/packages/CLPBN/horus/LiftedKc.h new file mode 100644 index 000000000..fbef33e0a --- /dev/null +++ b/packages/CLPBN/horus/LiftedKc.h @@ -0,0 +1,28 @@ +#ifndef HORUS_LIFTEDKC_H +#define HORUS_LIFTEDKC_H + +#include "ParfactorList.h" + +class LiftedWCNF; +class LiftedCircuit; + +class LiftedKc +{ + public: + LiftedKc (const ParfactorList& pfList); + + ~LiftedKc (void); + + Params solveQuery (const Grounds&); + + void printSolverFlags (void) const; + + private: + LiftedWCNF* lwcnf_; + LiftedCircuit* circuit_; + + const ParfactorList& pfList_; +}; + +#endif // HORUS_LIFTEDKC_H + diff --git a/packages/CLPBN/horus/Makefile.in b/packages/CLPBN/horus/Makefile.in index 10a99f782..e4c5b5178 100644 --- a/packages/CLPBN/horus/Makefile.in +++ b/packages/CLPBN/horus/Makefile.in @@ -58,6 +58,7 @@ HEADERS = \ $(srcdir)/Indexer.h \ $(srcdir)/LiftedBp.h \ $(srcdir)/LiftedCircuit.h \ + $(srcdir)/LiftedKc.h \ $(srcdir)/LiftedUtils.h \ $(srcdir)/LiftedVe.h \ $(srcdir)/LiftedWCNF.h \ @@ -84,7 +85,8 @@ CPP_SOURCES = \ $(srcdir)/HorusCli.cpp \ $(srcdir)/HorusYap.cpp \ $(srcdir)/LiftedBp.cpp \ - $(srcdir)/LiftedCircuit.h \ + $(srcdir)/LiftedCircuit.cpp \ + $(srcdir)/LiftedKc.cpp \ $(srcdir)/LiftedUtils.cpp \ $(srcdir)/LiftedVe.cpp \ $(srcdir)/LiftedWCNF.cpp \ @@ -110,6 +112,7 @@ OBJS = \ HorusYap.o \ LiftedBp.o \ LiftedCircuit.o \ + LiftedKc.o \ LiftedUtils.o \ LiftedVe.o \ LiftedWCNF.o \ From 8ab622e0aa4ab0dfcbfc502f7f2ac318fbfac9ae Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Fri, 9 Nov 2012 18:42:21 +0000 Subject: [PATCH 39/52] more work to support inference with lifted knowledge compilation --- packages/CLPBN/horus/LiftedCircuit.cpp | 10 +--- packages/CLPBN/horus/LiftedCircuit.h | 76 +++++++++++++------------- packages/CLPBN/horus/LiftedKc.cpp | 42 +++++++++++++- packages/CLPBN/horus/LiftedKc.h | 2 +- packages/CLPBN/horus/LiftedWCNF.cpp | 72 +++++++++++++----------- packages/CLPBN/horus/LiftedWCNF.h | 12 ++-- 6 files changed, 127 insertions(+), 87 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index cb7ba75a4..ab6ffac91 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -190,7 +190,7 @@ LiftedCircuit::LiftedCircuit (const LiftedWCNF* lwcnf) Clauses clauses = lwcnf->clauses(); compile (&root_, clauses); exportToGraphViz("circuit.dot"); - smoothCircuit(); + smoothCircuit (root_); exportToGraphViz("circuit.smooth.dot"); cout << "--------------------------------------------------" << endl; cout << "--------------------------------------------------" << endl; @@ -199,14 +199,6 @@ LiftedCircuit::LiftedCircuit (const LiftedWCNF* lwcnf) -void -LiftedCircuit::smoothCircuit (void) -{ - smoothCircuit (root_); -} - - - double LiftedCircuit::getWeightedModelCount (void) const { diff --git a/packages/CLPBN/horus/LiftedCircuit.h b/packages/CLPBN/horus/LiftedCircuit.h index 073de64fe..b040af3c5 100644 --- a/packages/CLPBN/horus/LiftedCircuit.h +++ b/packages/CLPBN/horus/LiftedCircuit.h @@ -25,15 +25,15 @@ class CircuitNode public: CircuitNode (const Clauses& clauses, string explanation = "") : clauses_(clauses), explanation_(explanation) { } - + const Clauses& clauses (void) const { return clauses_; } - + Clauses clauses (void) { return clauses_; } - + virtual double weight (void) const = 0; - + string explanation (void) const { return explanation_; } - + private: Clauses clauses_; string explanation_; @@ -50,7 +50,7 @@ class OrNode : public CircuitNode CircuitNode** leftBranch (void) { return &leftBranch_; } CircuitNode** rightBranch (void) { return &rightBranch_; } - + double weight (void) const; private: @@ -66,7 +66,7 @@ class AndNode : public CircuitNode AndNode (const Clauses& clauses, string explanation = "") : CircuitNode (clauses, explanation), leftBranch_(0), rightBranch_(0) { } - + AndNode ( const Clauses& clauses, CircuitNode* leftBranch, @@ -74,7 +74,7 @@ class AndNode : public CircuitNode string explanation = "") : CircuitNode (clauses, explanation), leftBranch_(leftBranch), rightBranch_(rightBranch) { } - + AndNode ( CircuitNode* leftBranch, CircuitNode* rightBranch, @@ -84,9 +84,9 @@ class AndNode : public CircuitNode CircuitNode** leftBranch (void) { return &leftBranch_; } CircuitNode** rightBranch (void) { return &rightBranch_; } - + double weight (void) const; - + private: CircuitNode* leftBranch_; CircuitNode* rightBranch_; @@ -106,7 +106,7 @@ class SetOrNode : public CircuitNode static unsigned nrPositives (void) { return nrGrsStack.top().first; } static unsigned nrNegatives (void) { return nrGrsStack.top().second; } - + double weight (void) const; private: @@ -126,7 +126,7 @@ class SetAndNode : public CircuitNode nrGroundings_(nrGroundings) { } CircuitNode** follow (void) { return &follow_; } - + double weight (void) const; private: @@ -146,7 +146,7 @@ class IncExcNode : public CircuitNode CircuitNode** plus1Branch (void) { return &plus1Branch_; } CircuitNode** plus2Branch (void) { return &plus2Branch_; } CircuitNode** minusBranch (void) { return &minusBranch_; } - + double weight (void) const; private: @@ -164,7 +164,7 @@ class LeafNode : public CircuitNode : CircuitNode (Clauses() = {clause}), lwcnf_(lwcnf) { } double weight (void) const; - + private: const LiftedWCNF& lwcnf_; }; @@ -189,7 +189,7 @@ class TrueNode : public CircuitNode { public: TrueNode (void) : CircuitNode ({}) { } - + double weight (void) const; }; @@ -200,7 +200,7 @@ class CompilationFailedNode : public CircuitNode public: CompilationFailedNode (const Clauses& clauses) : CircuitNode (clauses) { } - + double weight (void) const; }; @@ -210,62 +210,60 @@ class LiftedCircuit { public: LiftedCircuit (const LiftedWCNF* lwcnf); - - void smoothCircuit (void); - + 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); - + bool tryGrounding (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 (const CircuitNode* node, ofstream&, string extraOptions = ""); - + string escapeNode (const CircuitNode* node) const; CircuitNode* root_; diff --git a/packages/CLPBN/horus/LiftedKc.cpp b/packages/CLPBN/horus/LiftedKc.cpp index 7566a6d90..fb036df33 100644 --- a/packages/CLPBN/horus/LiftedKc.cpp +++ b/packages/CLPBN/horus/LiftedKc.cpp @@ -1,6 +1,7 @@ #include "LiftedKc.h" #include "LiftedWCNF.h" #include "LiftedCircuit.h" +#include "Indexer.h" LiftedKc::LiftedKc (const ParfactorList& pfList) @@ -19,9 +20,46 @@ LiftedKc::~LiftedKc (void) Params -LiftedKc::solveQuery (const Grounds&) +LiftedKc::solveQuery (const Grounds& query) { - return Params(); + 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; + } + } + cout << "groups: " << groups << endl; + cout << "ranges: " << ranges << endl; + 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], 1.0, 1.0); // TODO not log aware + } else { + lwcnf_->addWeight (litIds[j], 0.0, 1.0); // TODO not log aware + } + } + } + // cout << "new weights ----- ----- -----" << endl; + // lwcnf_->printWeights(); + // circuit_->exportToGraphViz ("ccircuit.dot"); + params.push_back (circuit_->getWeightedModelCount()); + ++ indexer; + } + cout << "params: " << params << endl; + LogAware::normalize (params); + return params; } diff --git a/packages/CLPBN/horus/LiftedKc.h b/packages/CLPBN/horus/LiftedKc.h index fbef33e0a..eb0074213 100644 --- a/packages/CLPBN/horus/LiftedKc.h +++ b/packages/CLPBN/horus/LiftedKc.h @@ -20,7 +20,7 @@ class LiftedKc private: LiftedWCNF* lwcnf_; LiftedCircuit* circuit_; - + const ParfactorList& pfList_; }; diff --git a/packages/CLPBN/horus/LiftedWCNF.cpp b/packages/CLPBN/horus/LiftedWCNF.cpp index 31641187e..7bf249923 100644 --- a/packages/CLPBN/horus/LiftedWCNF.cpp +++ b/packages/CLPBN/horus/LiftedWCNF.cpp @@ -352,8 +352,8 @@ Clause::getLogVarSetExcluding (size_t idx) const LiftedWCNF::LiftedWCNF (const ParfactorList& pfList) : freeLiteralId_(0), pfList_(pfList) { - //addIndicatorClauses (pfList); - //addParameterClauses (pfList); + addIndicatorClauses (pfList); + addParameterClauses (pfList); /* vector> names = { @@ -377,25 +377,25 @@ LiftedWCNF::LiftedWCNF (const ParfactorList& pfList) freeLiteralId_ = 2; */ - - Literal lit1 (0, {0}); - Literal lit2 (1, {0}); - Literal lit3 (2, {1}); - Literal lit4 (3, {1}); - - vector> names = {{"p1","p2"},{"p3","p4"}}; - Clause c1 (names); - c1.addLiteral (lit1); - c1.addLiteral (lit2); - c1.addLiteral (lit3); - c1.addLiteral (lit4); - //c1.addPosCountedLogVar (0); - clauses_.push_back (c1); - Clause c2 (names); - c2.addLiteral (lit1); - c2.addLiteral (lit3); - c2.addNegCountedLogVar (0); + //Literal lit1 (0, {0}); + //Literal lit2 (1, {0}); + //Literal lit3 (2, {1}); + //Literal lit4 (3, {1}); + + //vector> names = {{"p1","p2"},{"p3","p4"}}; + //Clause c1 (names); + //c1.addLiteral (lit1); + //c1.addLiteral (lit2); + //c1.addLiteral (lit3); + //c1.addLiteral (lit4); + //c1.addPosCountedLogVar (0); + //clauses_.push_back (c1); + + //Clause c2 (names); + //c2.addLiteral (lit1); + //c2.addLiteral (lit3); + //c2.addNegCountedLogVar (0); //clauses_.push_back (c2); /* Clause c3; @@ -408,17 +408,18 @@ LiftedWCNF::LiftedWCNF (const ParfactorList& pfList) c4.addLiteral (lit3); clauses_.push_back (c4); */ - freeLiteralId_ = 4; + //freeLiteralId_ = 4; cout << "FORMULA INDICATORS:" << endl; - // printFormulaIndicators(); + printFormulaIndicators(); cout << endl; + cout << "WEIGHTS:" << endl; printWeights(); cout << endl; + cout << "CLAUSES:" << endl; printClauses(); - // abort(); cout << endl; } @@ -431,6 +432,14 @@ LiftedWCNF::~LiftedWCNF (void) +void +LiftedWCNF::addWeight (LiteralId lid, double posW, double negW) +{ + weights_[lid] = make_pair (posW, negW); +} + + + double LiftedWCNF::posWeight (LiteralId lid) const { @@ -451,6 +460,15 @@ LiftedWCNF::negWeight (LiteralId lid) const +vector +LiftedWCNF::prvGroupLiterals (PrvGroup prvGroup) +{ + assert (Util::contains (map_, prvGroup)); + return map_[prvGroup]; +} + + + Clause LiftedWCNF::createClause (LiteralId lid) const { @@ -481,14 +499,6 @@ LiftedWCNF::getLiteralId (PrvGroup prvGroup, unsigned range) -void -LiftedWCNF::addWeight (LiteralId lid, double posW, double negW) -{ - weights_[lid] = make_pair (posW, negW); -} - - - void LiftedWCNF::addIndicatorClauses (const ParfactorList& pfList) { diff --git a/packages/CLPBN/horus/LiftedWCNF.h b/packages/CLPBN/horus/LiftedWCNF.h index 263593cbf..4163b60d8 100644 --- a/packages/CLPBN/horus/LiftedWCNF.h +++ b/packages/CLPBN/horus/LiftedWCNF.h @@ -188,13 +188,17 @@ class LiftedWCNF 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; @@ -204,10 +208,8 @@ class LiftedWCNF void printClauses (void) const; private: - + LiteralId getLiteralId (PrvGroup prvGroup, unsigned range); - - void addWeight (LiteralId lid, double posW, double negW); void addIndicatorClauses (const ParfactorList& pfList); From 07bcc89a76bb55b3efa1361e63f108397cfaaeeb Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Fri, 9 Nov 2012 23:52:35 +0000 Subject: [PATCH 40/52] factor out some lifted operations in a new class --- packages/CLPBN/horus/HorusYap.cpp | 3 +- packages/CLPBN/horus/LiftedBp.cpp | 3 +- packages/CLPBN/horus/LiftedBp.h | 1 + packages/CLPBN/horus/LiftedOperations.cpp | 211 +++++++++++++++++++++ packages/CLPBN/horus/LiftedOperations.h | 24 +++ packages/CLPBN/horus/LiftedVe.cpp | 215 +--------------------- packages/CLPBN/horus/LiftedVe.h | 4 - packages/CLPBN/horus/Makefile.in | 3 + 8 files changed, 248 insertions(+), 216 deletions(-) create mode 100644 packages/CLPBN/horus/LiftedOperations.cpp create mode 100644 packages/CLPBN/horus/LiftedOperations.h diff --git a/packages/CLPBN/horus/HorusYap.cpp b/packages/CLPBN/horus/HorusYap.cpp index 7246beb5e..cd31c0612 100644 --- a/packages/CLPBN/horus/HorusYap.cpp +++ b/packages/CLPBN/horus/HorusYap.cpp @@ -9,6 +9,7 @@ #include "ParfactorList.h" #include "FactorGraph.h" +#include "LiftedOperations.h" #include "LiftedVe.h" #include "VarElim.h" #include "LiftedBp.h" @@ -281,7 +282,7 @@ runLiftedSolver (void) YAP_Term taskList = YAP_ARG2; vector results; ParfactorList pfListCopy (*network->first); - LiftedVe::absorveEvidence (pfListCopy, *network->second); + LiftedOperations::absorveEvidence (pfListCopy, *network->second); while (taskList != YAP_TermNil()) { Grounds queryVars; YAP_Term jointList = YAP_HeadOfTerm (taskList); diff --git a/packages/CLPBN/horus/LiftedBp.cpp b/packages/CLPBN/horus/LiftedBp.cpp index 05a5ea6af..1c5a93023 100644 --- a/packages/CLPBN/horus/LiftedBp.cpp +++ b/packages/CLPBN/horus/LiftedBp.cpp @@ -1,6 +1,7 @@ #include "LiftedBp.h" #include "WeightedBp.h" #include "FactorGraph.h" +#include "LiftedOperations.h" #include "LiftedVe.h" @@ -101,7 +102,7 @@ LiftedBp::iterate (void) for (size_t i = 0; i < args.size(); i++) { LogVarSet lvs = (*it)->logVarSet() - args[i].logVars(); if ((*it)->constr()->isCountNormalized (lvs) == false) { - Parfactors pfs = LiftedVe::countNormalize (*it, lvs); + Parfactors pfs = LiftedOperations::countNormalize (*it, lvs); it = pfList_.removeAndDelete (it); pfList_.add (pfs); return false; diff --git a/packages/CLPBN/horus/LiftedBp.h b/packages/CLPBN/horus/LiftedBp.h index c34956320..29edf0ac8 100644 --- a/packages/CLPBN/horus/LiftedBp.h +++ b/packages/CLPBN/horus/LiftedBp.h @@ -39,3 +39,4 @@ class LiftedBp }; #endif // HORUS_LIFTEDBP_H + diff --git a/packages/CLPBN/horus/LiftedOperations.cpp b/packages/CLPBN/horus/LiftedOperations.cpp new file mode 100644 index 000000000..1c9c8b413 --- /dev/null +++ b/packages/CLPBN/horus/LiftedOperations.cpp @@ -0,0 +1,211 @@ +#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 (0); + } + 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::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/horus/LiftedOperations.h b/packages/CLPBN/horus/LiftedOperations.h new file mode 100644 index 000000000..ae6b6f0a9 --- /dev/null +++ b/packages/CLPBN/horus/LiftedOperations.h @@ -0,0 +1,24 @@ +#ifndef HORUS_LIFTEDOPERATIONS_H +#define HORUS_LIFTEDOPERATIONS_H + +#include "ParfactorList.h" + +class LiftedOperations +{ + public: + static void shatterAgainstQuery ( + ParfactorList& pfList, const Grounds& query); + + 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/horus/LiftedVe.cpp b/packages/CLPBN/horus/LiftedVe.cpp index 2437906ce..0b5435295 100644 --- a/packages/CLPBN/horus/LiftedVe.cpp +++ b/packages/CLPBN/horus/LiftedVe.cpp @@ -2,6 +2,7 @@ #include #include "LiftedVe.h" +#include "LiftedOperations.h" #include "Histogram.h" #include "Util.h" @@ -221,7 +222,7 @@ SumOutOperator::apply (void) product->sumOutIndex (fIdx); pfList_.addShattered (product); } else { - Parfactors pfs = LiftedVe::countNormalize (product, excl); + Parfactors pfs = LiftedOperations::countNormalize (product, excl); for (size_t i = 0; i < pfs.size(); i++) { pfs[i]->sumOutIndex (fIdx); pfList_.add (pfs[i]); @@ -375,7 +376,7 @@ CountingOperator::apply (void) } else { Parfactor* pf = *pfIter_; pfList_.remove (pfIter_); - Parfactors pfs = LiftedVe::countNormalize (pf, X_); + 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 ( @@ -419,7 +420,7 @@ CountingOperator::toString (void) ss << "count convert " << X_ << " in " ; ss << (*pfIter_)->getLabel(); ss << " [cost=" << std::exp (getLogCost()) << "]" << endl; - Parfactors pfs = LiftedVe::countNormalize (*pfIter_, X_); + 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; @@ -655,102 +656,11 @@ LiftedVe::printSolverFlags (void) const -void -LiftedVe::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 -LiftedVe::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 -LiftedVe::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]); -} - - - void LiftedVe::runSolver (const Grounds& query) { largestCost_ = std::log (0); - shatterAgainstQuery (query); + LiftedOperations::shatterAgainstQuery (pfList_, query); runWeakBayesBall (query); while (true) { if (Globals::verbosity > 2) { @@ -876,118 +786,3 @@ LiftedVe::runWeakBayesBall (const Grounds& query) } } - - -void -LiftedVe::shatterAgainstQuery (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 (0); - } - 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(); - } -} - - - -Parfactors -LiftedVe::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 = 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/horus/LiftedVe.h b/packages/CLPBN/horus/LiftedVe.h index e79ffc265..85adacc18 100644 --- a/packages/CLPBN/horus/LiftedVe.h +++ b/packages/CLPBN/horus/LiftedVe.h @@ -144,10 +144,6 @@ class LiftedVe static void absorveEvidence ( ParfactorList& pfList, ObservedFormulas& obsFormulas); - static Parfactors countNormalize (Parfactor*, const LogVarSet&); - - static Parfactor calcGroundMultiplication (Parfactor pf); - private: void runSolver (const Grounds&); diff --git a/packages/CLPBN/horus/Makefile.in b/packages/CLPBN/horus/Makefile.in index e4c5b5178..a87b3574e 100644 --- a/packages/CLPBN/horus/Makefile.in +++ b/packages/CLPBN/horus/Makefile.in @@ -59,6 +59,7 @@ HEADERS = \ $(srcdir)/LiftedBp.h \ $(srcdir)/LiftedCircuit.h \ $(srcdir)/LiftedKc.h \ + $(srcdir)/LiftedOperations.h \ $(srcdir)/LiftedUtils.h \ $(srcdir)/LiftedVe.h \ $(srcdir)/LiftedWCNF.h \ @@ -87,6 +88,7 @@ CPP_SOURCES = \ $(srcdir)/LiftedBp.cpp \ $(srcdir)/LiftedCircuit.cpp \ $(srcdir)/LiftedKc.cpp \ + $(srcdir)/LiftedOperations.cpp \ $(srcdir)/LiftedUtils.cpp \ $(srcdir)/LiftedVe.cpp \ $(srcdir)/LiftedWCNF.cpp \ @@ -113,6 +115,7 @@ OBJS = \ LiftedBp.o \ LiftedCircuit.o \ LiftedKc.o \ + LiftedOperations.o \ LiftedUtils.o \ LiftedVe.o \ LiftedWCNF.o \ From 47768176031d5e1d301b0211f31f3257ddad3d89 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Sat, 10 Nov 2012 00:18:20 +0000 Subject: [PATCH 41/52] move more code around --- packages/CLPBN/horus/LiftedBp.cpp | 17 +++---- packages/CLPBN/horus/LiftedOperations.cpp | 61 +++++++++++++++++++++++ packages/CLPBN/horus/LiftedOperations.h | 4 +- packages/CLPBN/horus/LiftedVe.cpp | 61 +---------------------- packages/CLPBN/horus/LiftedVe.h | 26 +++------- 5 files changed, 81 insertions(+), 88 deletions(-) diff --git a/packages/CLPBN/horus/LiftedBp.cpp b/packages/CLPBN/horus/LiftedBp.cpp index 1c5a93023..468e79d72 100644 --- a/packages/CLPBN/horus/LiftedBp.cpp +++ b/packages/CLPBN/horus/LiftedBp.cpp @@ -2,7 +2,6 @@ #include "WeightedBp.h" #include "FactorGraph.h" #include "LiftedOperations.h" -#include "LiftedVe.h" LiftedBp::LiftedBp (const ParfactorList& pfList) @@ -190,12 +189,12 @@ LiftedBp::rangeOfGround (const Ground& gr) Params LiftedBp::getJointByConditioning ( const ParfactorList& pfList, - const Grounds& grounds) + const Grounds& query) { LiftedBp solver (pfList); - Params prevBeliefs = solver.solveQuery ({grounds[0]}); - Grounds obsGrounds = {grounds[0]}; - for (size_t i = 1; i < grounds.size(); i++) { + 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; @@ -210,16 +209,16 @@ LiftedBp::getJointByConditioning ( obsFs[j].setEvidence (indexer[j]); } ParfactorList tempPfList (pfList); - LiftedVe::absorveEvidence (tempPfList, obsFs); + LiftedOperations::absorveEvidence (tempPfList, obsFs); LiftedBp solver (tempPfList); - Params beliefs = solver.solveQuery ({grounds[i]}); + 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 (grounds[i]); + unsigned range = rangeOfGround (query[i]); for (size_t j = 0; j < newBeliefs.size(); j++) { if (j % range == 0) { count ++; @@ -227,7 +226,7 @@ LiftedBp::getJointByConditioning ( newBeliefs[j] *= prevBeliefs[count]; } prevBeliefs = newBeliefs; - obsGrounds.push_back (grounds[i]); + obsGrounds.push_back (query[i]); } return prevBeliefs; } diff --git a/packages/CLPBN/horus/LiftedOperations.cpp b/packages/CLPBN/horus/LiftedOperations.cpp index 1c9c8b413..ec40695a7 100644 --- a/packages/CLPBN/horus/LiftedOperations.cpp +++ b/packages/CLPBN/horus/LiftedOperations.cpp @@ -54,6 +54,67 @@ LiftedOperations::shatterAgainstQuery ( +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, diff --git a/packages/CLPBN/horus/LiftedOperations.h b/packages/CLPBN/horus/LiftedOperations.h index ae6b6f0a9..1e21f317c 100644 --- a/packages/CLPBN/horus/LiftedOperations.h +++ b/packages/CLPBN/horus/LiftedOperations.h @@ -9,6 +9,9 @@ class LiftedOperations static void shatterAgainstQuery ( ParfactorList& pfList, const Grounds& query); + static void runWeakBayesBall ( + ParfactorList& pfList, const Grounds&); + static void absorveEvidence ( ParfactorList& pfList, ObservedFormulas& obsFormulas); @@ -17,7 +20,6 @@ class LiftedOperations static Parfactor calcGroundMultiplication (Parfactor pf); private: - static Parfactors absorve (ObservedFormula&, Parfactor*); }; diff --git a/packages/CLPBN/horus/LiftedVe.cpp b/packages/CLPBN/horus/LiftedVe.cpp index 0b5435295..add7a36a6 100644 --- a/packages/CLPBN/horus/LiftedVe.cpp +++ b/packages/CLPBN/horus/LiftedVe.cpp @@ -661,7 +661,7 @@ LiftedVe::runSolver (const Grounds& query) { largestCost_ = std::log (0); LiftedOperations::shatterAgainstQuery (pfList_, query); - runWeakBayesBall (query); + LiftedOperations::runWeakBayesBall (pfList_, query); while (true) { if (Globals::verbosity > 2) { Util::printDashedLine(); @@ -727,62 +727,3 @@ LiftedVe::getBestOperation (const Grounds& query) return bestOp; } - - -void -LiftedVe::runWeakBayesBall (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; - } - } -} - diff --git a/packages/CLPBN/horus/LiftedVe.h b/packages/CLPBN/horus/LiftedVe.h index 85adacc18..9a464a348 100644 --- a/packages/CLPBN/horus/LiftedVe.h +++ b/packages/CLPBN/horus/LiftedVe.h @@ -45,9 +45,9 @@ class ProductOperator : public LiftedOperator private: static bool validOp (Parfactor*, Parfactor*); - ParfactorList::iterator g1_; - ParfactorList::iterator g2_; - ParfactorList& pfList_; + ParfactorList::iterator g1_; + ParfactorList::iterator g2_; + ParfactorList& pfList_; }; @@ -125,9 +125,9 @@ class GroundOperator : public LiftedOperator private: vector> getAffectedFormulas (void); - PrvGroup group_; - unsigned lvIndex_; - ParfactorList& pfList_; + PrvGroup group_; + unsigned lvIndex_; + ParfactorList& pfList_; }; @@ -141,23 +141,13 @@ class LiftedVe void printSolverFlags (void) const; - static void absorveEvidence ( - ParfactorList& pfList, ObservedFormulas& obsFormulas); - private: void runSolver (const Grounds&); LiftedOperator* getBestOperation (const Grounds&); - void runWeakBayesBall (const Grounds&); - - void shatterAgainstQuery (const Grounds&); - - static Parfactors absorve (ObservedFormula&, Parfactor*); - - ParfactorList pfList_; - - double largestCost_; + ParfactorList pfList_; + double largestCost_; }; #endif // HORUS_LIFTEDVE_H From f5c85ffcc95875ddc496ab1e20db0bb510c5cbf8 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Mon, 12 Nov 2012 15:20:42 +0000 Subject: [PATCH 42/52] shatter agains the query in lifted knowledge compilation --- packages/CLPBN/horus/LiftedKc.cpp | 10 ++++++++-- packages/CLPBN/horus/LiftedKc.h | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/CLPBN/horus/LiftedKc.cpp b/packages/CLPBN/horus/LiftedKc.cpp index fb036df33..ee7f56bfe 100644 --- a/packages/CLPBN/horus/LiftedKc.cpp +++ b/packages/CLPBN/horus/LiftedKc.cpp @@ -1,20 +1,22 @@ #include "LiftedKc.h" #include "LiftedWCNF.h" #include "LiftedCircuit.h" +#include "LiftedOperations.h" #include "Indexer.h" LiftedKc::LiftedKc (const ParfactorList& pfList) : pfList_(pfList) { - lwcnf_ = new LiftedWCNF (pfList); - circuit_ = new LiftedCircuit (lwcnf_); + } LiftedKc::~LiftedKc (void) { + delete lwcnf_; + delete circuit_; } @@ -22,6 +24,9 @@ LiftedKc::~LiftedKc (void) Params LiftedKc::solveQuery (const Grounds& query) { + LiftedOperations::shatterAgainstQuery (pfList_, query); + lwcnf_ = new LiftedWCNF (pfList_); + circuit_ = new LiftedCircuit (lwcnf_); vector groups; Ranges ranges; for (size_t i = 0; i < query.size(); i++) { @@ -36,6 +41,7 @@ LiftedKc::solveQuery (const Grounds& query) ++ it; } } + assert (groups.size() == query.size()); cout << "groups: " << groups << endl; cout << "ranges: " << ranges << endl; Params params; diff --git a/packages/CLPBN/horus/LiftedKc.h b/packages/CLPBN/horus/LiftedKc.h index eb0074213..4b3065c1d 100644 --- a/packages/CLPBN/horus/LiftedKc.h +++ b/packages/CLPBN/horus/LiftedKc.h @@ -21,7 +21,7 @@ class LiftedKc LiftedWCNF* lwcnf_; LiftedCircuit* circuit_; - const ParfactorList& pfList_; + ParfactorList pfList_; }; #endif // HORUS_LIFTEDKC_H From 9202e286f8fa196dd9329dcbd085bf7eaf47dcd6 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Wed, 14 Nov 2012 14:43:56 +0000 Subject: [PATCH 43/52] IncExc: check if log vars are count normalized --- packages/CLPBN/horus/LiftedCircuit.cpp | 22 ++++++++++++++-------- packages/CLPBN/horus/LiftedOperations.cpp | 1 - 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index ab6ffac91..f5d43ef8f 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -37,14 +37,15 @@ SetOrNode::weight (void) const double w = std::log (Util::nrCombinations (nrGroundings_, i)); weightSum = Util::logSum (weightSum, w + follow_->weight()); } else { - cout << endl; - cout << "nr groundings = " << nrGroundings_ << endl; - cout << "nr positives = " << nrPositives() << endl; - cout << "nr negatives = " << nrNegatives() << endl; - cout << "i = " << i << endl; - cout << "nr combos = " << Util::nrCombinations (nrGroundings_, i) << endl; + // cout << endl; + // cout << "nr groundings = " << nrGroundings_ << endl; + // cout << "nr positives = " << nrPositives() << endl; + // cout << "nr negatives = " << nrNegatives() << endl; + // cout << "i = " << i << endl; + // cout << "nr combos = " ; + // cout << Util::nrCombinations (nrGroundings_, i) << endl; double w = follow_->weight(); - cout << "weight = " << w << endl; + // cout << "weight = " << w << endl; weightSum += Util::nrCombinations (nrGroundings_, i) * w; } } @@ -411,15 +412,20 @@ LiftedCircuit::tryInclusionExclusion ( } } if (indepLits.empty() == false) { - // TODO this should be have to be count normalized too 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 (clauses[i].constr().projectedCopy (lvs1)); for (size_t j = 0; j < depLits.size(); j++) { c1.addLiteral (depLits[j]); diff --git a/packages/CLPBN/horus/LiftedOperations.cpp b/packages/CLPBN/horus/LiftedOperations.cpp index ec40695a7..03cafdee7 100644 --- a/packages/CLPBN/horus/LiftedOperations.cpp +++ b/packages/CLPBN/horus/LiftedOperations.cpp @@ -269,4 +269,3 @@ LiftedOperations::absorve ( return absorvedPfs; } - From d9e48e6290294fcf535d41b067c8e11de85fda4d Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Wed, 14 Nov 2012 18:40:03 +0000 Subject: [PATCH 44/52] log domain calculations fixes for lifted knowledge compilation --- packages/CLPBN/horus/LiftedCircuit.cpp | 38 ++++++++------------------ packages/CLPBN/horus/LiftedKc.cpp | 10 +++++-- 2 files changed, 19 insertions(+), 29 deletions(-) diff --git a/packages/CLPBN/horus/LiftedCircuit.cpp b/packages/CLPBN/horus/LiftedCircuit.cpp index f5d43ef8f..b3f5a653a 100644 --- a/packages/CLPBN/horus/LiftedCircuit.cpp +++ b/packages/CLPBN/horus/LiftedCircuit.cpp @@ -18,6 +18,11 @@ AndNode::weight (void) const { double lw = leftBranch_->weight(); double rw = rightBranch_->weight(); + if (Globals::logDomain) { +// cout << "andw1 = " << std::exp(lw + rw) << endl; + } else { +// cout << "andw2 = " << lw * rw << endl; + } return Globals::logDomain ? lw + rw : lw * rw; } @@ -34,18 +39,11 @@ SetOrNode::weight (void) const for (unsigned i = 0; i < nrGroundings_ + 1; i++) { nrGrsStack.push (make_pair (nrGroundings_ - i, i)); if (Globals::logDomain) { - double w = std::log (Util::nrCombinations (nrGroundings_, i)); - weightSum = Util::logSum (weightSum, w + follow_->weight()); - } else { - // cout << endl; - // cout << "nr groundings = " << nrGroundings_ << endl; - // cout << "nr positives = " << nrPositives() << endl; - // cout << "nr negatives = " << nrNegatives() << endl; - // cout << "i = " << i << endl; - // cout << "nr combos = " ; - // cout << Util::nrCombinations (nrGroundings_, i) << endl; + double nrCombs = Util::nrCombinations (nrGroundings_, i); + double w = follow_->weight(); + weightSum = Util::logSum (weightSum, std::log (nrCombs) + w); + } else { double w = follow_->weight(); - // cout << "weight = " << w << endl; weightSum += Util::nrCombinations (nrGroundings_, i) * w; } } @@ -100,20 +98,14 @@ LeafNode::weight (void) const ct.project (lvs); nrGroundings = ct.size(); } - // cout << "calc weight for " << clauses().front() << endl; if (c.posCountedLogVars().empty() == false) { - // cout << " -> nr pos = " << SetOrNode::nrPositives() << endl; nrGroundings *= std::pow (SetOrNode::nrPositives(), c.nrPosCountedLogVars()); } if (c.negCountedLogVars().empty() == false) { - //cout << " -> nr neg = " << SetOrNode::nrNegatives() << endl; nrGroundings *= std::pow (SetOrNode::nrNegatives(), c.nrNegCountedLogVars()); } - // cout << " -> nr groundings = " << nrGroundings << endl; - // cout << " -> lit weight = " << weight << endl; - // cout << " -> ret weight = " << std::pow (weight, nrGroundings) << endl; return Globals::logDomain ? weight * nrGroundings : std::pow (weight, nrGroundings); @@ -139,26 +131,19 @@ SmoothNode::weight (void) const ct.project (lvs); nrGroundings = ct.size(); } - // cout << "calc smooth weight for " << cs[i] << endl; if (cs[i].posCountedLogVars().empty() == false) { - // cout << " -> nr pos = " << SetOrNode::nrPositives() << endl; nrGroundings *= std::pow (SetOrNode::nrPositives(), cs[i].nrPosCountedLogVars()); } if (cs[i].negCountedLogVars().empty() == false) { - // cout << " -> nr neg = " << SetOrNode::nrNegatives() << endl; nrGroundings *= std::pow (SetOrNode::nrNegatives(), cs[i].nrNegCountedLogVars()); } - // cout << " -> pos+neg = " << posWeight + negWeight << endl; - // cout << " -> nrgroun = " << nrGroundings << endl; if (Globals::logDomain) { - totalWeight += (Util::logSum (posWeight, negWeight) - * std::log (nrGroundings)); + totalWeight += Util::logSum (posWeight, negWeight) * nrGroundings; } else { totalWeight *= std::pow (posWeight + negWeight, nrGroundings); } - // cout << " -> smooth weight = " << totalWeight << endl; } return totalWeight; } @@ -195,7 +180,8 @@ LiftedCircuit::LiftedCircuit (const LiftedWCNF* lwcnf) exportToGraphViz("circuit.smooth.dot"); cout << "--------------------------------------------------" << endl; cout << "--------------------------------------------------" << endl; - cout << "WEIGHTED MODEL COUNT = " << getWeightedModelCount() << endl; + double wmc = LogAware::exp (getWeightedModelCount()); + cout << "WEIGHTED MODEL COUNT = " << wmc << endl; } diff --git a/packages/CLPBN/horus/LiftedKc.cpp b/packages/CLPBN/horus/LiftedKc.cpp index ee7f56bfe..63d6c1d62 100644 --- a/packages/CLPBN/horus/LiftedKc.cpp +++ b/packages/CLPBN/horus/LiftedKc.cpp @@ -51,9 +51,11 @@ LiftedKc::solveQuery (const Grounds& query) vector litIds = lwcnf_->prvGroupLiterals (groups[i]); for (size_t j = 0; j < litIds.size(); j++) { if (indexer[i] == j) { - lwcnf_->addWeight (litIds[j], 1.0, 1.0); // TODO not log aware + lwcnf_->addWeight (litIds[j], LogAware::one(), + LogAware::one()); } else { - lwcnf_->addWeight (litIds[j], 0.0, 1.0); // TODO not log aware + lwcnf_->addWeight (litIds[j], LogAware::zero(), + LogAware::one()); } } } @@ -63,8 +65,10 @@ LiftedKc::solveQuery (const Grounds& query) params.push_back (circuit_->getWeightedModelCount()); ++ indexer; } - cout << "params: " << params << endl; LogAware::normalize (params); + if (Globals::logDomain) { + Util::exp (params); + } return params; } From cad22da9f5286388d01c4b487e9e917ca434bf40 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Wed, 14 Nov 2012 21:05:55 +0000 Subject: [PATCH 45/52] fixes & cleanups --- packages/CLPBN/horus/LiftedKc.cpp | 5 --- packages/CLPBN/horus/LiftedWCNF.cpp | 59 ++++++++++------------------- 2 files changed, 19 insertions(+), 45 deletions(-) diff --git a/packages/CLPBN/horus/LiftedKc.cpp b/packages/CLPBN/horus/LiftedKc.cpp index 63d6c1d62..69aed3f33 100644 --- a/packages/CLPBN/horus/LiftedKc.cpp +++ b/packages/CLPBN/horus/LiftedKc.cpp @@ -42,8 +42,6 @@ LiftedKc::solveQuery (const Grounds& query) } } assert (groups.size() == query.size()); - cout << "groups: " << groups << endl; - cout << "ranges: " << ranges << endl; Params params; Indexer indexer (ranges); while (indexer.valid()) { @@ -59,9 +57,6 @@ LiftedKc::solveQuery (const Grounds& query) } } } - // cout << "new weights ----- ----- -----" << endl; - // lwcnf_->printWeights(); - // circuit_->exportToGraphViz ("ccircuit.dot"); params.push_back (circuit_->getWeightedModelCount()); ++ indexer; } diff --git a/packages/CLPBN/horus/LiftedWCNF.cpp b/packages/CLPBN/horus/LiftedWCNF.cpp index 7bf249923..3d635b16b 100644 --- a/packages/CLPBN/horus/LiftedWCNF.cpp +++ b/packages/CLPBN/horus/LiftedWCNF.cpp @@ -356,60 +356,39 @@ LiftedWCNF::LiftedWCNF (const ParfactorList& pfList) addParameterClauses (pfList); /* + // INCLUSION-EXCLUSION TEST + vector> names = { + // {"a1","b1"},{"a2","b2"},{"a1","b3"} + {"b1","a1"},{"b2","a2"},{"b3","a1"} + }; + Clause c1 (names); + c1.addLiteral (Literal (0, LogVars() = {0})); + c1.addLiteral (Literal (1, LogVars() = {1})); + clauses_.push_back(c1); + freeLiteralId_ ++ ; + freeLiteralId_ ++ ; + */ + + /* + // ATOM-COUNTING TEST vector> names = { {"p1","p1"},{"p1","p2"},{"p1","p3"}, {"p2","p1"},{"p2","p2"},{"p2","p3"}, {"p3","p1"},{"p3","p2"},{"p3","p3"} }; - Clause c1 (names); c1.addLiteral (Literal (0, LogVars() = {0})); c1.addLiteralComplemented (Literal (1, {0,1})); clauses_.push_back(c1); - Clause c2 (names); c2.addLiteral (Literal (0, LogVars()={0})); c2.addLiteralComplemented (Literal (1, {1,0})); clauses_.push_back(c2); - - addWeight (0, 3.0, 4.0); - addWeight (1, 2.0, 5.0); - + addWeight (0, LogAware::log(3.0), LogAware::log(4.0)); + addWeight (1, LogAware::log(2.0), LogAware::log(5.0)); freeLiteralId_ = 2; */ - - //Literal lit1 (0, {0}); - //Literal lit2 (1, {0}); - //Literal lit3 (2, {1}); - //Literal lit4 (3, {1}); - - //vector> names = {{"p1","p2"},{"p3","p4"}}; - //Clause c1 (names); - //c1.addLiteral (lit1); - //c1.addLiteral (lit2); - //c1.addLiteral (lit3); - //c1.addLiteral (lit4); - //c1.addPosCountedLogVar (0); - //clauses_.push_back (c1); - - //Clause c2 (names); - //c2.addLiteral (lit1); - //c2.addLiteral (lit3); - //c2.addNegCountedLogVar (0); - //clauses_.push_back (c2); - /* - Clause c3; - c3.addLiteral (lit3); - c3.addLiteral (lit4); - clauses_.push_back (c3); - Clause c4; - c4.addLiteral (lit4); - c4.addLiteral (lit3); - clauses_.push_back (c4); - */ - //freeLiteralId_ = 4; - cout << "FORMULA INDICATORS:" << endl; printFormulaIndicators(); cout << endl; @@ -445,7 +424,7 @@ LiftedWCNF::posWeight (LiteralId lid) const { unordered_map>::const_iterator it; it = weights_.find (lid); - return it != weights_.end() ? it->second.first : 1.0; + return it != weights_.end() ? it->second.first : LogAware::one(); } @@ -455,7 +434,7 @@ LiftedWCNF::negWeight (LiteralId lid) const { unordered_map>::const_iterator it; it = weights_.find (lid); - return it != weights_.end() ? it->second.second : 1.0; + return it != weights_.end() ? it->second.second : LogAware::one(); } From 6e7d0d1d0a502bdce8bd15c0c9ea0ca382e1c124 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Wed, 14 Nov 2012 21:17:04 +0000 Subject: [PATCH 46/52] remove old TODOs --- packages/CLPBN/horus/LiftedVe.cpp | 2 -- packages/CLPBN/horus/TODO | 2 -- 2 files changed, 4 deletions(-) diff --git a/packages/CLPBN/horus/LiftedVe.cpp b/packages/CLPBN/horus/LiftedVe.cpp index add7a36a6..eedce1f21 100644 --- a/packages/CLPBN/horus/LiftedVe.cpp +++ b/packages/CLPBN/horus/LiftedVe.cpp @@ -509,8 +509,6 @@ GroundOperator::getLogCost (void) void GroundOperator::apply (void) { - // TODO if we update the correct groups - // we can skip shattering ParfactorList::iterator pfIter; pfIter = getParfactorsWithGroup (pfList_, group_).front(); Parfactor* pf = *pfIter; diff --git a/packages/CLPBN/horus/TODO b/packages/CLPBN/horus/TODO index c2afafb0b..360fa65ca 100644 --- a/packages/CLPBN/horus/TODO +++ b/packages/CLPBN/horus/TODO @@ -1,4 +1,2 @@ - Handle formulas like f(X,X) -- Find a way to decrease the time required to find an - elimination order for variable elimination From 64a27847cc0a9df49be59a389e4200032035d422 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Wed, 14 Nov 2012 21:55:51 +0000 Subject: [PATCH 47/52] Introduce a lifted solver class --- packages/CLPBN/horus/BeliefProp.cpp | 5 +- packages/CLPBN/horus/BeliefProp.h | 4 +- packages/CLPBN/horus/CountingBp.cpp | 6 +- packages/CLPBN/horus/CountingBp.h | 4 +- packages/CLPBN/horus/Horus.h | 8 +-- packages/CLPBN/horus/HorusCli.cpp | 8 +-- packages/CLPBN/horus/HorusYap.cpp | 14 ++-- packages/CLPBN/horus/LiftedBp.cpp | 2 +- packages/CLPBN/horus/LiftedBp.h | 3 +- packages/CLPBN/horus/LiftedKc.cpp | 8 --- packages/CLPBN/horus/LiftedKc.h | 7 +- packages/CLPBN/horus/LiftedVe.h | 7 +- packages/CLPBN/horus/Makefile.in | 9 +-- packages/CLPBN/horus/Solver.cpp | 107 ---------------------------- packages/CLPBN/horus/Solver.h | 36 ---------- packages/CLPBN/horus/Util.cpp | 16 ++--- packages/CLPBN/horus/VarElim.h | 6 +- 17 files changed, 53 insertions(+), 197 deletions(-) delete mode 100644 packages/CLPBN/horus/Solver.cpp delete mode 100644 packages/CLPBN/horus/Solver.h diff --git a/packages/CLPBN/horus/BeliefProp.cpp b/packages/CLPBN/horus/BeliefProp.cpp index 314f4a6c5..d96384cfd 100644 --- a/packages/CLPBN/horus/BeliefProp.cpp +++ b/packages/CLPBN/horus/BeliefProp.cpp @@ -12,7 +12,7 @@ #include "Horus.h" -BeliefProp::BeliefProp (const FactorGraph& fg) : Solver (fg) +BeliefProp::BeliefProp (const FactorGraph& fg) : GroundSolver (fg) { runned_ = false; } @@ -377,7 +377,8 @@ BeliefProp::getVarToFactorMsg (const BpLink* link) const Params BeliefProp::getJointByConditioning (const VarIds& jointVarIds) const { - return Solver::getJointByConditioning (GroundSolver::BP, fg, jointVarIds); + return GroundSolver::getJointByConditioning ( + GroundSolverType::BP, fg, jointVarIds); } diff --git a/packages/CLPBN/horus/BeliefProp.h b/packages/CLPBN/horus/BeliefProp.h index 1545abfc8..6c1d5c46b 100644 --- a/packages/CLPBN/horus/BeliefProp.h +++ b/packages/CLPBN/horus/BeliefProp.h @@ -5,7 +5,7 @@ #include #include -#include "Solver.h" +#include "GroundSolver.h" #include "Factor.h" #include "FactorGraph.h" #include "Util.h" @@ -83,7 +83,7 @@ class SPNodeInfo }; -class BeliefProp : public Solver +class BeliefProp : public GroundSolver { public: BeliefProp (const FactorGraph&); diff --git a/packages/CLPBN/horus/CountingBp.cpp b/packages/CLPBN/horus/CountingBp.cpp index 365ff7098..d248c602c 100644 --- a/packages/CLPBN/horus/CountingBp.cpp +++ b/packages/CLPBN/horus/CountingBp.cpp @@ -6,7 +6,7 @@ bool CountingBp::checkForIdenticalFactors = true; CountingBp::CountingBp (const FactorGraph& fg) - : Solver (fg), freeColor_(0) + : GroundSolver (fg), freeColor_(0) { findIdenticalFactors(); setInitialColors(); @@ -74,8 +74,8 @@ CountingBp::solveQuery (VarIds queryVids) cout << endl; } if (idx == facNodes.size()) { - res = Solver::getJointByConditioning ( - GroundSolver::CBP, fg, queryVids); + res = GroundSolver::getJointByConditioning ( + GroundSolverType::CBP, fg, queryVids); } else { VarIds reprArgs; for (size_t i = 0; i < queryVids.size(); i++) { diff --git a/packages/CLPBN/horus/CountingBp.h b/packages/CLPBN/horus/CountingBp.h index 7bc45c632..a553e9307 100644 --- a/packages/CLPBN/horus/CountingBp.h +++ b/packages/CLPBN/horus/CountingBp.h @@ -3,7 +3,7 @@ #include -#include "Solver.h" +#include "GroundSolver.h" #include "FactorGraph.h" #include "Util.h" #include "Horus.h" @@ -102,7 +102,7 @@ class FacCluster }; -class CountingBp : public Solver +class CountingBp : public GroundSolver { public: CountingBp (const FactorGraph& fg); diff --git a/packages/CLPBN/horus/Horus.h b/packages/CLPBN/horus/Horus.h index 2c8d20e1e..7e5f12c8e 100644 --- a/packages/CLPBN/horus/Horus.h +++ b/packages/CLPBN/horus/Horus.h @@ -28,7 +28,7 @@ typedef vector Ranges; typedef unsigned long long ullong; -enum LiftedSolver +enum LiftedSolverType { LVE, // generalized counting first-order variable elimination (GC-FOVE) LBP, // lifted first-order belief propagation @@ -36,7 +36,7 @@ enum LiftedSolver }; -enum GroundSolver +enum GroundSolverType { VE, // variable elimination BP, // belief propagation @@ -51,8 +51,8 @@ extern bool logDomain; // level of debug information extern unsigned verbosity; -extern LiftedSolver liftedSolver; -extern GroundSolver groundSolver; +extern LiftedSolverType liftedSolver; +extern GroundSolverType groundSolver; }; diff --git a/packages/CLPBN/horus/HorusCli.cpp b/packages/CLPBN/horus/HorusCli.cpp index 4c3f8e7fc..639b91739 100644 --- a/packages/CLPBN/horus/HorusCli.cpp +++ b/packages/CLPBN/horus/HorusCli.cpp @@ -160,15 +160,15 @@ readQueryAndEvidence ( void runSolver (const FactorGraph& fg, const VarIds& queryIds) { - Solver* solver = 0; + GroundSolver* solver = 0; switch (Globals::groundSolver) { - case GroundSolver::VE: + case GroundSolverType::VE: solver = new VarElim (fg); break; - case GroundSolver::BP: + case GroundSolverType::BP: solver = new BeliefProp (fg); break; - case GroundSolver::CBP: + case GroundSolverType::CBP: solver = new CountingBp (fg); break; default: diff --git a/packages/CLPBN/horus/HorusYap.cpp b/packages/CLPBN/horus/HorusYap.cpp index cd31c0612..2fa0008fb 100644 --- a/packages/CLPBN/horus/HorusYap.cpp +++ b/packages/CLPBN/horus/HorusYap.cpp @@ -308,21 +308,21 @@ runLiftedSolver (void) } jointList = YAP_TailOfTerm (jointList); } - if (Globals::liftedSolver == LiftedSolver::LVE) { + if (Globals::liftedSolver == LiftedSolverType::LVE) { LiftedVe solver (pfListCopy); if (Globals::verbosity > 0 && taskList == YAP_ARG2) { solver.printSolverFlags(); cout << endl; } results.push_back (solver.solveQuery (queryVars)); - } else if (Globals::liftedSolver == LiftedSolver::LBP) { + } else if (Globals::liftedSolver == LiftedSolverType::LBP) { LiftedBp solver (pfListCopy); if (Globals::verbosity > 0 && taskList == YAP_ARG2) { solver.printSolverFlags(); cout << endl; } results.push_back (solver.solveQuery (queryVars)); - } else if (Globals::liftedSolver == LiftedSolver::LKC) { + } else if (Globals::liftedSolver == LiftedSolverType::LKC) { LiftedKc solver (pfListCopy); if (Globals::verbosity > 0 && taskList == YAP_ARG2) { solver.printSolverFlags(); @@ -369,18 +369,18 @@ runGroundSolver (void) for (size_t i = 0; i < tasks.size(); i++) { Util::addToSet (vids, tasks[i]); } - Solver* solver = 0; + GroundSolver* solver = 0; FactorGraph* mfg = fg; if (fg->bayesianFactors()) { mfg = BayesBall::getMinimalFactorGraph ( *fg, VarIds (vids.begin(), vids.end())); } - if (Globals::groundSolver == GroundSolver::VE) { + if (Globals::groundSolver == GroundSolverType::VE) { solver = new VarElim (*mfg); - } else if (Globals::groundSolver == GroundSolver::BP) { + } else if (Globals::groundSolver == GroundSolverType::BP) { solver = new BeliefProp (*mfg); - } else if (Globals::groundSolver == GroundSolver::CBP) { + } else if (Globals::groundSolver == GroundSolverType::CBP) { CountingBp::checkForIdenticalFactors = false; solver = new CountingBp (*mfg); } else { diff --git a/packages/CLPBN/horus/LiftedBp.cpp b/packages/CLPBN/horus/LiftedBp.cpp index 468e79d72..3fada048d 100644 --- a/packages/CLPBN/horus/LiftedBp.cpp +++ b/packages/CLPBN/horus/LiftedBp.cpp @@ -5,7 +5,7 @@ LiftedBp::LiftedBp (const ParfactorList& pfList) - : pfList_(pfList) + : LiftedSolver (pfList), pfList_(pfList) { refineParfactors(); createFactorGraph(); diff --git a/packages/CLPBN/horus/LiftedBp.h b/packages/CLPBN/horus/LiftedBp.h index 29edf0ac8..cb6e9f3a4 100644 --- a/packages/CLPBN/horus/LiftedBp.h +++ b/packages/CLPBN/horus/LiftedBp.h @@ -1,12 +1,13 @@ #ifndef HORUS_LIFTEDBP_H #define HORUS_LIFTEDBP_H +#include "LiftedSolver.h" #include "ParfactorList.h" class FactorGraph; class WeightedBp; -class LiftedBp +class LiftedBp : public LiftedSolver { public: LiftedBp (const ParfactorList& pfList); diff --git a/packages/CLPBN/horus/LiftedKc.cpp b/packages/CLPBN/horus/LiftedKc.cpp index 69aed3f33..64e651379 100644 --- a/packages/CLPBN/horus/LiftedKc.cpp +++ b/packages/CLPBN/horus/LiftedKc.cpp @@ -5,14 +5,6 @@ #include "Indexer.h" -LiftedKc::LiftedKc (const ParfactorList& pfList) - : pfList_(pfList) -{ - -} - - - LiftedKc::~LiftedKc (void) { delete lwcnf_; diff --git a/packages/CLPBN/horus/LiftedKc.h b/packages/CLPBN/horus/LiftedKc.h index 4b3065c1d..52138c985 100644 --- a/packages/CLPBN/horus/LiftedKc.h +++ b/packages/CLPBN/horus/LiftedKc.h @@ -1,15 +1,18 @@ #ifndef HORUS_LIFTEDKC_H #define HORUS_LIFTEDKC_H +#include "LiftedSolver.h" #include "ParfactorList.h" class LiftedWCNF; class LiftedCircuit; -class LiftedKc + +class LiftedKc : public LiftedSolver { public: - LiftedKc (const ParfactorList& pfList); + LiftedKc (const ParfactorList& pfList) + : LiftedSolver(pfList), pfList_(pfList) { } ~LiftedKc (void); diff --git a/packages/CLPBN/horus/LiftedVe.h b/packages/CLPBN/horus/LiftedVe.h index 9a464a348..cdaf39823 100644 --- a/packages/CLPBN/horus/LiftedVe.h +++ b/packages/CLPBN/horus/LiftedVe.h @@ -1,7 +1,7 @@ #ifndef HORUS_LIFTEDVE_H #define HORUS_LIFTEDVE_H - +#include "LiftedSolver.h" #include "ParfactorList.h" @@ -132,10 +132,11 @@ class GroundOperator : public LiftedOperator -class LiftedVe +class LiftedVe : public LiftedSolver { public: - LiftedVe (const ParfactorList& pfList) : pfList_(pfList) { } + LiftedVe (const ParfactorList& pfList) + : LiftedSolver(pfList), pfList_(pfList) { } Params solveQuery (const Grounds&); diff --git a/packages/CLPBN/horus/Makefile.in b/packages/CLPBN/horus/Makefile.in index a87b3574e..59936c776 100644 --- a/packages/CLPBN/horus/Makefile.in +++ b/packages/CLPBN/horus/Makefile.in @@ -60,13 +60,14 @@ HEADERS = \ $(srcdir)/LiftedCircuit.h \ $(srcdir)/LiftedKc.h \ $(srcdir)/LiftedOperations.h \ + $(srcdir)/LiftedSolver.h \ $(srcdir)/LiftedUtils.h \ $(srcdir)/LiftedVe.h \ $(srcdir)/LiftedWCNF.h \ $(srcdir)/Parfactor.h \ $(srcdir)/ParfactorList.h \ $(srcdir)/ProbFormula.h \ - $(srcdir)/Solver.h \ + $(srcdir)/GroundSolver.h \ $(srcdir)/TinySet.h \ $(srcdir)/Util.h \ $(srcdir)/Var.h \ @@ -95,7 +96,7 @@ CPP_SOURCES = \ $(srcdir)/Parfactor.cpp \ $(srcdir)/ParfactorList.cpp \ $(srcdir)/ProbFormula.cpp \ - $(srcdir)/Solver.cpp \ + $(srcdir)/GroundSolver.cpp \ $(srcdir)/Util.cpp \ $(srcdir)/Var.cpp \ $(srcdir)/VarElim.cpp \ @@ -122,7 +123,7 @@ OBJS = \ ProbFormula.o \ Parfactor.o \ ParfactorList.o \ - Solver.o \ + GroundSolver.o \ Util.o \ Var.o \ VarElim.o \ @@ -137,7 +138,7 @@ HCLI_OBJS = \ Factor.o \ FactorGraph.o \ HorusCli.o \ - Solver.o \ + GroundSolver.o \ Util.o \ Var.o \ VarElim.o \ diff --git a/packages/CLPBN/horus/Solver.cpp b/packages/CLPBN/horus/Solver.cpp deleted file mode 100644 index 4cb3b6768..000000000 --- a/packages/CLPBN/horus/Solver.cpp +++ /dev/null @@ -1,107 +0,0 @@ -#include "Solver.h" -#include "Util.h" -#include "BeliefProp.h" -#include "CountingBp.h" -#include "VarElim.h" - - -void -Solver::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 -Solver::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 -Solver::getJointByConditioning ( - GroundSolver 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])); - } - - Solver* solver = 0; - switch (solverType) { - case GroundSolver::BP: solver = new BeliefProp (fg); break; - case GroundSolver::CBP: solver = new CountingBp (fg); break; - case GroundSolver::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 GroundSolver::BP: solver = new BeliefProp (fg); break; - case GroundSolver::CBP: solver = new CountingBp (fg); break; - case GroundSolver::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/horus/Solver.h b/packages/CLPBN/horus/Solver.h deleted file mode 100644 index a378b2419..000000000 --- a/packages/CLPBN/horus/Solver.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef HORUS_SOLVER_H -#define HORUS_SOLVER_H - -#include - -#include "FactorGraph.h" -#include "Var.h" -#include "Horus.h" - - -using namespace std; - -class Solver -{ - public: - Solver (const FactorGraph& factorGraph) : fg(factorGraph) { } - - virtual ~Solver() { } // 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 (GroundSolver, - FactorGraph, const VarIds& jointVarIds) const; - - protected: - const FactorGraph& fg; -}; - -#endif // HORUS_SOLVER_H - diff --git a/packages/CLPBN/horus/Util.cpp b/packages/CLPBN/horus/Util.cpp index bef3414c6..d3dbd588d 100644 --- a/packages/CLPBN/horus/Util.cpp +++ b/packages/CLPBN/horus/Util.cpp @@ -13,9 +13,9 @@ bool logDomain = false; unsigned verbosity = 0; -LiftedSolver liftedSolver = LiftedSolver::LVE; +LiftedSolverType liftedSolver = LiftedSolverType::LVE; -GroundSolver groundSolver = GroundSolver::VE; +GroundSolverType groundSolver = GroundSolverType::VE; }; @@ -211,11 +211,11 @@ setHorusFlag (string key, string value) ss >> Globals::verbosity; } else if (key == "lifted_solver") { if ( value == "lve") { - Globals::liftedSolver = LiftedSolver::LVE; + Globals::liftedSolver = LiftedSolverType::LVE; } else if (value == "lbp") { - Globals::liftedSolver = LiftedSolver::LBP; + Globals::liftedSolver = LiftedSolverType::LBP; } else if (value == "lkc") { - Globals::liftedSolver = LiftedSolver::LKC; + Globals::liftedSolver = LiftedSolverType::LKC; } else { cerr << "warning: invalid value `" << value << "' " ; cerr << "for `" << key << "'" << endl; @@ -223,11 +223,11 @@ setHorusFlag (string key, string value) } } else if (key == "ground_solver") { if ( value == "ve") { - Globals::groundSolver = GroundSolver::VE; + Globals::groundSolver = GroundSolverType::VE; } else if (value == "bp") { - Globals::groundSolver = GroundSolver::BP; + Globals::groundSolver = GroundSolverType::BP; } else if (value == "cbp") { - Globals::groundSolver = GroundSolver::CBP; + Globals::groundSolver = GroundSolverType::CBP; } else { cerr << "warning: invalid value `" << value << "' " ; cerr << "for `" << key << "'" << endl; diff --git a/packages/CLPBN/horus/VarElim.h b/packages/CLPBN/horus/VarElim.h index 6fbaded8c..fe1327fc0 100644 --- a/packages/CLPBN/horus/VarElim.h +++ b/packages/CLPBN/horus/VarElim.h @@ -3,7 +3,7 @@ #include "unordered_map" -#include "Solver.h" +#include "GroundSolver.h" #include "FactorGraph.h" #include "Horus.h" @@ -11,10 +11,10 @@ using namespace std; -class VarElim : public Solver +class VarElim : public GroundSolver { public: - VarElim (const FactorGraph& fg) : Solver (fg) { } + VarElim (const FactorGraph& fg) : GroundSolver (fg) { } ~VarElim (void); From b673dfd46274b4444f01441df96ff27785917dda Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Wed, 14 Nov 2012 23:12:03 +0000 Subject: [PATCH 48/52] fix type in an example --- packages/CLPBN/examples/city.yap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/CLPBN/examples/city.yap b/packages/CLPBN/examples/city.yap index 3647698cc..a133b42c2 100644 --- a/packages/CLPBN/examples/city.yap +++ b/packages/CLPBN/examples/city.yap @@ -29,7 +29,7 @@ bayes car_color(P)::[t,f], hair_color(P) ; car_color_table(P); [people(P,_)]. bayes height(P)::[t,f], gender(P) ; height_table(P) ; [people(P,_)]. -bayes shoe_size(P):[t,f], height(P) ; shoe_size_table(P); [people(P,_)]. +bayes shoe_size(P)::[t,f], height(P) ; shoe_size_table(P); [people(P,_)]. bayes guilty(P)::[y,n] ; guilty_table(P) ; [people(P,_)]. From 4522850cd699e84a9ed4cd59833f547a5bc0050a Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Wed, 14 Nov 2012 23:13:46 +0000 Subject: [PATCH 49/52] one step close to use one solver instatiation to solve several queries --- packages/CLPBN/horus/LiftedBp.cpp | 5 +++-- packages/CLPBN/horus/LiftedKc.cpp | 2 ++ packages/CLPBN/horus/LiftedKc.h | 9 ++++----- packages/CLPBN/horus/LiftedVe.cpp | 1 + packages/CLPBN/horus/LiftedVe.h | 2 +- packages/CLPBN/horus/ParfactorList.cpp | 24 ++++++++++++++++++++++-- packages/CLPBN/horus/ParfactorList.h | 2 ++ 7 files changed, 35 insertions(+), 10 deletions(-) diff --git a/packages/CLPBN/horus/LiftedBp.cpp b/packages/CLPBN/horus/LiftedBp.cpp index 3fada048d..66e82a8c4 100644 --- a/packages/CLPBN/horus/LiftedBp.cpp +++ b/packages/CLPBN/horus/LiftedBp.cpp @@ -4,8 +4,8 @@ #include "LiftedOperations.h" -LiftedBp::LiftedBp (const ParfactorList& pfList) - : LiftedSolver (pfList), pfList_(pfList) +LiftedBp::LiftedBp (const ParfactorList& parfactorList) + : LiftedSolver (parfactorList) { refineParfactors(); createFactorGraph(); @@ -82,6 +82,7 @@ LiftedBp::printSolverFlags (void) const void LiftedBp::refineParfactors (void) { + pfList_ = parfactorList; while (iterate() == false); if (Globals::verbosity > 2) { diff --git a/packages/CLPBN/horus/LiftedKc.cpp b/packages/CLPBN/horus/LiftedKc.cpp index 64e651379..6c0aba622 100644 --- a/packages/CLPBN/horus/LiftedKc.cpp +++ b/packages/CLPBN/horus/LiftedKc.cpp @@ -16,7 +16,9 @@ LiftedKc::~LiftedKc (void) Params LiftedKc::solveQuery (const Grounds& query) { + pfList_ = parfactorList; LiftedOperations::shatterAgainstQuery (pfList_, query); + LiftedOperations::runWeakBayesBall (pfList_, query); lwcnf_ = new LiftedWCNF (pfList_); circuit_ = new LiftedCircuit (lwcnf_); vector groups; diff --git a/packages/CLPBN/horus/LiftedKc.h b/packages/CLPBN/horus/LiftedKc.h index 52138c985..cba6499e1 100644 --- a/packages/CLPBN/horus/LiftedKc.h +++ b/packages/CLPBN/horus/LiftedKc.h @@ -12,7 +12,7 @@ class LiftedKc : public LiftedSolver { public: LiftedKc (const ParfactorList& pfList) - : LiftedSolver(pfList), pfList_(pfList) { } + : LiftedSolver(pfList) { } ~LiftedKc (void); @@ -21,10 +21,9 @@ class LiftedKc : public LiftedSolver void printSolverFlags (void) const; private: - LiftedWCNF* lwcnf_; - LiftedCircuit* circuit_; - - ParfactorList pfList_; + LiftedWCNF* lwcnf_; + LiftedCircuit* circuit_; + ParfactorList pfList_; }; #endif // HORUS_LIFTEDKC_H diff --git a/packages/CLPBN/horus/LiftedVe.cpp b/packages/CLPBN/horus/LiftedVe.cpp index eedce1f21..141006c46 100644 --- a/packages/CLPBN/horus/LiftedVe.cpp +++ b/packages/CLPBN/horus/LiftedVe.cpp @@ -631,6 +631,7 @@ Params LiftedVe::solveQuery (const Grounds& query) { assert (query.empty() == false); + pfList_ = parfactorList; runSolver (query); (*pfList_.begin())->normalize(); Params params = (*pfList_.begin())->params(); diff --git a/packages/CLPBN/horus/LiftedVe.h b/packages/CLPBN/horus/LiftedVe.h index cdaf39823..7d9974294 100644 --- a/packages/CLPBN/horus/LiftedVe.h +++ b/packages/CLPBN/horus/LiftedVe.h @@ -136,7 +136,7 @@ class LiftedVe : public LiftedSolver { public: LiftedVe (const ParfactorList& pfList) - : LiftedSolver(pfList), pfList_(pfList) { } + : LiftedSolver(pfList) { } Params solveQuery (const Grounds&); diff --git a/packages/CLPBN/horus/ParfactorList.cpp b/packages/CLPBN/horus/ParfactorList.cpp index 8a1ca30d2..b4496a683 100644 --- a/packages/CLPBN/horus/ParfactorList.cpp +++ b/packages/CLPBN/horus/ParfactorList.cpp @@ -9,8 +9,7 @@ ParfactorList::ParfactorList (const ParfactorList& pfList) while (it != pfList.end()) { addShattered (new Parfactor (**it)); ++ it; - } - + } } @@ -126,6 +125,27 @@ ParfactorList::print (void) const +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 { diff --git a/packages/CLPBN/horus/ParfactorList.h b/packages/CLPBN/horus/ParfactorList.h index 9e65539bb..48008b253 100644 --- a/packages/CLPBN/horus/ParfactorList.h +++ b/packages/CLPBN/horus/ParfactorList.h @@ -56,6 +56,8 @@ class ParfactorList bool isAllShattered (void) const; void print (void) const; + + ParfactorList& operator= (const ParfactorList& pfList); private: From 51fd48cd46ede3b36ec9e22161a306781f8e1ec2 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Wed, 14 Nov 2012 23:17:39 +0000 Subject: [PATCH 50/52] Ouchgit statusgit status! forgot to add these to index --- packages/CLPBN/horus/GroundSolver.cpp | 107 ++++++++++++++++++++++++++ packages/CLPBN/horus/GroundSolver.h | 36 +++++++++ packages/CLPBN/horus/LiftedSolver.h | 27 +++++++ 3 files changed, 170 insertions(+) create mode 100644 packages/CLPBN/horus/GroundSolver.cpp create mode 100644 packages/CLPBN/horus/GroundSolver.h create mode 100644 packages/CLPBN/horus/LiftedSolver.h diff --git a/packages/CLPBN/horus/GroundSolver.cpp b/packages/CLPBN/horus/GroundSolver.cpp new file mode 100644 index 000000000..4cd3fdbd2 --- /dev/null +++ b/packages/CLPBN/horus/GroundSolver.cpp @@ -0,0 +1,107 @@ +#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/horus/GroundSolver.h b/packages/CLPBN/horus/GroundSolver.h new file mode 100644 index 000000000..3e2959605 --- /dev/null +++ b/packages/CLPBN/horus/GroundSolver.h @@ -0,0 +1,36 @@ +#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/horus/LiftedSolver.h b/packages/CLPBN/horus/LiftedSolver.h new file mode 100644 index 000000000..5429fc5b3 --- /dev/null +++ b/packages/CLPBN/horus/LiftedSolver.h @@ -0,0 +1,27 @@ +#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 + From 59fd21bf3368d0912f001d29b55e256d8d590e5b Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Fri, 16 Nov 2012 16:50:19 +0000 Subject: [PATCH 51/52] use only 1 lifted solver instance --- packages/CLPBN/horus/HorusYap.cpp | 64 +++++++++++++------------------ 1 file changed, 26 insertions(+), 38 deletions(-) diff --git a/packages/CLPBN/horus/HorusYap.cpp b/packages/CLPBN/horus/HorusYap.cpp index 2fa0008fb..b82cf1d76 100644 --- a/packages/CLPBN/horus/HorusYap.cpp +++ b/packages/CLPBN/horus/HorusYap.cpp @@ -276,13 +276,24 @@ readParameters (YAP_Term paramL) int runLiftedSolver (void) { - // TODO one solver instatiation should be used - // to solve several inference tasks LiftedNetwork* network = (LiftedNetwork*) YAP_IntOfTerm (YAP_ARG1); - YAP_Term taskList = YAP_ARG2; - vector results; 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); @@ -308,33 +319,12 @@ runLiftedSolver (void) } jointList = YAP_TailOfTerm (jointList); } - if (Globals::liftedSolver == LiftedSolverType::LVE) { - LiftedVe solver (pfListCopy); - if (Globals::verbosity > 0 && taskList == YAP_ARG2) { - solver.printSolverFlags(); - cout << endl; - } - results.push_back (solver.solveQuery (queryVars)); - } else if (Globals::liftedSolver == LiftedSolverType::LBP) { - LiftedBp solver (pfListCopy); - if (Globals::verbosity > 0 && taskList == YAP_ARG2) { - solver.printSolverFlags(); - cout << endl; - } - results.push_back (solver.solveQuery (queryVars)); - } else if (Globals::liftedSolver == LiftedSolverType::LKC) { - LiftedKc solver (pfListCopy); - if (Globals::verbosity > 0 && taskList == YAP_ARG2) { - solver.printSolverFlags(); - cout << endl; - } - results.push_back (solver.solveQuery (queryVars)); - } else { - assert (false); - } + results.push_back (solver->solveQuery (queryVars)); taskList = YAP_TailOfTerm (taskList); } + delete solver; + YAP_Term list = YAP_TermNil(); for (size_t i = results.size(); i-- > 0; ) { const Params& beliefs = results[i]; @@ -358,6 +348,7 @@ int runGroundSolver (void) { FactorGraph* fg = (FactorGraph*) YAP_IntOfTerm (YAP_ARG1); + vector tasks; YAP_Term taskList = YAP_ARG2; while (taskList != YAP_TermNil()) { @@ -369,22 +360,19 @@ runGroundSolver (void) for (size_t i = 0; i < tasks.size(); i++) { Util::addToSet (vids, tasks[i]); } - GroundSolver* solver = 0; + FactorGraph* mfg = fg; if (fg->bayesianFactors()) { mfg = BayesBall::getMinimalFactorGraph ( *fg, VarIds (vids.begin(), vids.end())); } - if (Globals::groundSolver == GroundSolverType::VE) { - solver = new VarElim (*mfg); - } else if (Globals::groundSolver == GroundSolverType::BP) { - solver = new BeliefProp (*mfg); - } else if (Globals::groundSolver == GroundSolverType::CBP) { - CountingBp::checkForIdenticalFactors = false; - solver = new CountingBp (*mfg); - } else { - assert (false); + 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) { From 51eef45b2dc359e9ac41dc430a8a41500ccf1d53 Mon Sep 17 00:00:00 2001 From: Tiago Gomes Date: Fri, 16 Nov 2012 17:10:04 +0000 Subject: [PATCH 52/52] refactor HorusYap --- packages/CLPBN/horus/HorusYap.cpp | 369 +++++++++++++++--------------- 1 file changed, 183 insertions(+), 186 deletions(-) diff --git a/packages/CLPBN/horus/HorusYap.cpp b/packages/CLPBN/horus/HorusYap.cpp index b82cf1d76..5810b2fff 100644 --- a/packages/CLPBN/horus/HorusYap.cpp +++ b/packages/CLPBN/horus/HorusYap.cpp @@ -24,25 +24,15 @@ using namespace std; typedef std::pair LiftedNetwork; -Params readParameters (YAP_Term); - -vector readUnsignedList (YAP_Term); +Parfactor* readParfactor (YAP_Term); void readLiftedEvidence (YAP_Term, ObservedFormulas&); -Parfactor* readParfactor (YAP_Term); +vector readUnsignedList (YAP_Term list); +Params readParameters (YAP_Term); -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; -} +YAP_Term fillAnswersPrologList (vector& results); @@ -85,132 +75,6 @@ createLiftedNetwork (void) -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: constraint has free variables" << endl; - abort(); - } - 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); - } -} - - - int createGroundNetwork (void) { @@ -256,23 +120,6 @@ createGroundNetwork (void) -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; -} - - - int runLiftedSolver (void) { @@ -325,21 +172,7 @@ runLiftedSolver (void) delete solver; - 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 YAP_Unify (list, YAP_ARG3); + return YAP_Unify (fillAnswersPrologList (results), YAP_ARG3); } @@ -391,20 +224,7 @@ runGroundSolver (void) delete mfg; } - 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 YAP_Unify (list, YAP_ARG3); + return YAP_Unify (fillAnswersPrologList (results), YAP_ARG3); } @@ -535,6 +355,183 @@ freeLiftedNetwork (void) +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: constraint has free variables" << endl; + abort(); + } + 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) {