void ConstraintTree::getTuples ( CTNode* n, Tuples currTuples, unsigned stopLevel, Tuples& tuplesCollected, CTNodes& continuationNodes) const { if (n->isRoot() == false) { if (currTuples.size() == 0) { currTuples.push_back ({ n->symbol()}); } else { for (size_t i = 0; i < currTuples.size(); i++) { currTuples[i].push_back (n->symbol()); } } if (n->level() == stopLevel) { for (size_t i = 0; i < currTuples.size(); i++) { tuplesCollected.push_back (currTuples[i]); continuationNodes.push_back (n); } return; } } const CTChilds& childs = n->childs(); for (CTChilds::const_iterator chIt = childs.begin(); chIt != childs.end(); ++ chIt) { getTuples (*chIt, currTuples, stopLevel, tuplesCollected, continuationNodes); } }
ConstraintTree::ConstraintTree ( const LogVars& logVars, const Tuples& tuples) { root_ = new CTNode (0, 0); logVars_ = logVars; logVarSet_ = LogVarSet (logVars); for (size_t i = 0; i < tuples.size(); i++) { addTuple (tuples[i]); } }
void ConstraintTree::join (ConstraintTree* ct, bool oneTwoOne) { if (logVarSet_.empty()) { CTNode::deleteSubtree (root_); root_ = CTNode::copySubtree (ct->root()); logVars_ = ct->logVars(); logVarSet_ = ct->logVarSet(); return; } if (oneTwoOne) { if (logVarSet_.contains (ct->logVarSet())) { return; } if (ct->logVarSet().contains (logVarSet_)) { CTNode::deleteSubtree (root_); root_ = CTNode::copySubtree (ct->root()); logVars_ = ct->logVars(); logVarSet_ = ct->logVarSet(); return; } } LogVarSet intersect = logVarSet_ & ct->logVarSet_; if (intersect.empty()) { // cartesian product appendOnBottom (root_, ct->root()->childs()); Util::addToVector (logVars_, ct->logVars_); logVarSet_ |= ct->logVarSet_; } else { moveToTop (intersect.elements()); ct->moveToTop (intersect.elements()); Tuples tuples; CTNodes appendNodes; getTuples (ct->root(), Tuples(), intersect.size(), tuples, appendNodes); CTNodes::const_iterator appendIt = appendNodes.begin(); for (size_t i = 0; i < tuples.size(); ++ i, ++ appendIt) { bool tupleFounded = join (root_, tuples[i], 0, *appendIt); if (oneTwoOne && tupleFounded == false) { assert (false); } } LogVars newLvs (ct->logVars().begin() + intersect.size(), ct->logVars().end()); Util::addToVector (logVars_, newLvs); logVarSet_ |= LogVarSet (newLvs); } }
TupleSet ConstraintTree::tupleSet (const LogVars& originalLvs) { LogVars uniqueLvs; for (size_t i = 0; i < originalLvs.size(); i++) { if (Util::contains (uniqueLvs, originalLvs[i]) == false) { uniqueLvs.push_back (originalLvs[i]); } } Tuples tuples; moveToTop (uniqueLvs); unsigned stopLevel = uniqueLvs.size(); getTuples (root_, Tuples(), stopLevel, tuples, CTNodes() = {}); if (originalLvs.size() != uniqueLvs.size()) { vector<size_t> indexes; indexes.reserve (originalLvs.size()); for (size_t i = 0; i < originalLvs.size(); i++) { indexes.push_back (Util::indexOf (uniqueLvs, originalLvs[i])); } Tuples tuples2; tuples2.reserve (tuples.size()); for (size_t i = 0; i < tuples.size(); i++) { Tuple t; t.reserve (originalLvs.size()); for (size_t j = 0; j < originalLvs.size(); j++) { t.push_back (tuples[i][indexes[j]]); } tuples2.push_back (t); } return TupleSet (tuples2); } return TupleSet (tuples); }