ItemTreePtr RuleIntroductionSolver::compute() { const auto nodeStackElement = app.getPrinter().visitNode(decomposition); assert(decomposition.getChildren().size() == 1); Decomposition& childNode = **decomposition.getChildren().begin(); ItemTreePtr childResult = childNode.getSolver().compute(); ItemTreePtr result; if(childResult) { result = extendRoot(childResult); assert(childResult->getChildren().empty() == false); for(const ItemTreePtr& childCandidate : childResult->getChildren()) { // Make introducedAtom false ItemTreeNode::Items candidateItems = childCandidate->getNode()->getItems(); ItemTreeNode::Items candidateAuxItems = childCandidate->getNode()->getAuxItems(); // Calculate false atoms of this candidate Hypergraph::Vertices candidateFalseAtoms; std::set_symmetric_difference(decomposition.getNode().getBag().begin(), decomposition.getNode().getBag().end(), candidateItems.begin(), candidateItems.end(), std::inserter(candidateFalseAtoms, candidateFalseAtoms.begin())); const bool introducedRuleDisappears = doesIntroducedRuleDisappear(candidateItems); if(introducedRuleDisappears || isIntroducedRuleSatisfied(candidateItems, candidateFalseAtoms)) candidateAuxItems.insert(introducedRule); ItemTreePtr candidate = extendCandidate(std::move(candidateItems), std::move(candidateAuxItems), childCandidate); for(const ItemTreePtr& childCertificate : childCandidate->getChildren()) { ItemTreeNode::Items certificateItems = childCertificate->getNode()->getItems(); ItemTreeNode::Items certificateAuxItems = childCertificate->getNode()->getAuxItems(); if(introducedRuleDisappears) certificateAuxItems.insert(introducedRule); else { // Calculate false atoms of this certificate Hypergraph::Vertices certificateFalseAtoms; std::set_symmetric_difference(decomposition.getNode().getBag().begin(), decomposition.getNode().getBag().end(), certificateItems.begin(), certificateItems.end(), std::inserter(certificateFalseAtoms, certificateFalseAtoms.begin())); if(isIntroducedRuleSatisfied(certificateItems, certificateFalseAtoms)) certificateAuxItems.insert(introducedRule); } candidate->addChildAndMerge(extendCertificate(std::move(certificateItems), std::move(certificateAuxItems), childCertificate)); } result->addChildAndMerge(std::move(candidate)); } assert(!decomposition.isRoot()); if(result->finalize(app, false, app.isPruningDisabled() == false || decomposition.isRoot()) == false) result.reset(); } app.getPrinter().solverInvocationResult(decomposition, result.get()); return result; }
ItemTreePtr AtomRemovalSolver::compute() { const auto nodeStackElement = app.getPrinter().visitNode(decomposition); assert(decomposition.getChildren().size() == 1); Decomposition& childNode = **decomposition.getChildren().begin(); ItemTreePtr childResult = childNode.getSolver().compute(); ItemTreePtr result; if(childResult) { result = extendRoot(childResult); assert(childResult->getChildren().empty() == false); // Guess node to extend at depth 1 for(const ItemTreePtr& childCandidate : childResult->getChildren()) { ItemTreeNode::Items candidateItems = childCandidate->getNode()->getItems(); candidateItems.erase(removedAtom); ItemTreeNode::Items candidateAuxItems = childCandidate->getNode()->getAuxItems(); ItemTreePtr candidate = extendCandidate(std::move(candidateItems), std::move(candidateAuxItems), childCandidate); for(const ItemTreePtr& childCertificate : childCandidate->getChildren()) { ItemTreeNode::Items certificateItems = childCertificate->getNode()->getItems(); certificateItems.erase(removedAtom); ItemTreeNode::Items certificateAuxItems = childCertificate->getNode()->getAuxItems(); const ItemTreeNode::Type type = decomposition.isRoot() ? (certificateAuxItems.find(String("smaller")) == certificateAuxItems.end() ? ItemTreeNode::Type::ACCEPT : ItemTreeNode::Type::REJECT) : ItemTreeNode::Type::UNDEFINED; candidate->addChildAndMerge(extendCertificate(std::move(certificateItems), std::move(certificateAuxItems), childCertificate, type)); } result->addChildAndMerge(std::move(candidate)); } if(result->finalize(app, decomposition.isRoot(), app.isPruningDisabled() == false || decomposition.isRoot()) == false) result.reset(); } app.getPrinter().solverInvocationResult(decomposition, result.get()); return result; }
ItemTreePtr AtomIntroductionSolver::compute() { const auto nodeStackElement = app.getPrinter().visitNode(decomposition); assert(decomposition.getChildren().size() == 1); Decomposition& childNode = **decomposition.getChildren().begin(); ItemTreePtr childResult = childNode.getSolver().compute(); ItemTreePtr result; if(childResult) { result = extendRoot(childResult); assert(childResult->getChildren().empty() == false); // Find out which rules are satisfied by setting introducedAtom to true or false, respectively, and which disappear from the reduct by setting introducedAtom to true. // TODO unordered_set? Rules rulesSatisfiedByTrue; Rules rulesSatisfiedByFalse; Rules rulesDisappearingByTrue; for(String bagElement : decomposition.getNode().getBag()) { AtomsInRule::const_iterator it = heads.find(bagElement); if(it != heads.end() && it->second.find(introducedAtom) != it->second.end()) rulesSatisfiedByTrue.insert(bagElement); it = positiveBody.find(bagElement); if(it != positiveBody.end() && it->second.find(introducedAtom) != it->second.end()) rulesSatisfiedByFalse.insert(bagElement); it = negativeBody.find(bagElement); if(it != negativeBody.end() && it->second.find(introducedAtom) != it->second.end()) { rulesSatisfiedByTrue.insert(bagElement); rulesDisappearingByTrue.insert(bagElement); } } // Guess node to extend at depth 1 for(const ItemTreePtr& childCandidate : childResult->getChildren()) { // Make introducedAtom false ItemTreeNode::Items candidateItems = childCandidate->getNode()->getItems(); ItemTreeNode::Items candidateAuxItems = childCandidate->getNode()->getAuxItems(); // Add satisfied rules candidateAuxItems.insert(rulesSatisfiedByFalse.begin(), rulesSatisfiedByFalse.end()); ItemTreePtr candidate = extendCandidate(std::move(candidateItems), std::move(candidateAuxItems), childCandidate); for(const ItemTreePtr& childCertificate : childCandidate->getChildren()) { ItemTreeNode::Items certificateItems = childCertificate->getNode()->getItems(); ItemTreeNode::Items certificateAuxItems = childCertificate->getNode()->getAuxItems(); // Add satisfied rules certificateAuxItems.insert(rulesSatisfiedByFalse.begin(), rulesSatisfiedByFalse.end()); candidate->addChildAndMerge(extendCertificate(std::move(certificateItems), std::move(certificateAuxItems), childCertificate)); } result->addChildAndMerge(std::move(candidate)); // Make introducedAtom true candidateItems = childCandidate->getNode()->getItems(); candidateItems.insert(introducedAtom); candidateAuxItems = childCandidate->getNode()->getAuxItems(); // Add satisfied rules candidateAuxItems.insert(rulesSatisfiedByTrue.begin(), rulesSatisfiedByTrue.end()); candidate = extendCandidate(std::move(candidateItems), std::move(candidateAuxItems), childCandidate); for(const ItemTreePtr& childCertificate : childCandidate->getChildren()) { // Make introducedAtom false in certificate (and add "smaller" flag) ItemTreeNode::Items certificateItems = childCertificate->getNode()->getItems(); ItemTreeNode::Items certificateAuxItems = childCertificate->getNode()->getAuxItems(); certificateAuxItems.emplace("smaller"); certificateAuxItems.insert(rulesDisappearingByTrue.begin(), rulesDisappearingByTrue.end()); certificateAuxItems.insert(rulesSatisfiedByFalse.begin(), rulesSatisfiedByFalse.end()); candidate->addChildAndMerge(extendCertificate(std::move(certificateItems), std::move(certificateAuxItems), childCertificate)); // Make introducedAtom true in certificate certificateItems = childCertificate->getNode()->getItems(); certificateItems.insert(introducedAtom); certificateAuxItems = childCertificate->getNode()->getAuxItems(); certificateAuxItems.insert(rulesSatisfiedByTrue.begin(), rulesSatisfiedByTrue.end()); candidate->addChildAndMerge(extendCertificate(std::move(certificateItems), std::move(certificateAuxItems), childCertificate)); } result->addChildAndMerge(std::move(candidate)); } assert(!decomposition.isRoot()); if(result->finalize(app, false, app.isPruningDisabled() == false || decomposition.isRoot()) == false) result.reset(); } app.getPrinter().solverInvocationResult(decomposition, result.get()); return result; }