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; }
void Solver::handleRowCandidate(long costBound) { // ++models; assert(asyncResult); const Clasp::Model& m = asyncResult->model(); // Get items {{{ ItemTreeNode::Items items; asp_utils::forEachTrue(m, itemAtomInfos, [&items](const GringoOutputProcessor::ItemAtomArguments& arguments) { items.insert(arguments.item); }); ItemTreeNode::Items auxItems; asp_utils::forEachTrue(m, auxItemAtomInfos, [&auxItems](const GringoOutputProcessor::AuxItemAtomArguments& arguments) { auxItems.insert(arguments.item); }); ASP_CHECK(std::find_if(items.begin(), items.end(), [&auxItems](const String& item) { return auxItems.find(item) != auxItems.end(); }) == items.end(), "Items and auxiliary items not disjoint"); // }}} // FIXME Do proper cost computations, not this item-set cardinality proof of concept // Compute cost {{{ // ASP_CHECK(asp_utils::countTrue(m, costAtomInfos) <= 1, "More than one true cost/1 atom"); // long cost = 0; // asp_utils::forFirstTrue(m, costAtomInfos, [&cost](const GringoOutputProcessor::CostAtomArguments& arguments) { // cost = arguments.cost; // }); // node->setCost(cost); long cost = items.size(); for(const auto& row : getCurrentRowCombination()) { const auto& oldItems = row->getItems(); ItemTreeNode::Items intersection; std::set_intersection(items.begin(), items.end(), oldItems.begin(), oldItems.end(), std::inserter(intersection, intersection.begin())); cost += row->getCost() - intersection.size(); } // }}} if(cost >= costBound) { // ++discardedModels; newestRow = itemTree->getChildren().end(); return; } assert(itemTree); // Create item tree node {{{ std::shared_ptr<ItemTreeNode> node(new ItemTreeNode(std::move(items), std::move(auxItems), {getCurrentRowCombination()})); // }}} if(!app.isOptimizationDisabled()) { // Set cost {{{ node->setCost(cost); // }}} // Set current cost {{{ // ASP_CHECK(asp_utils::countTrue(m, currentCostAtomInfos) <= 1, "More than one true currentCost/1 atom"); // ASP_CHECK(asp_utils::countTrue(m, currentCostAtomInfos) == 0 || asp_utils::countTrue(m, costAtomInfos) == 1, "True currentCost/1 atom without true cost/1 atom"); // long currentCost = 0; // asp_utils::forFirstTrue(m, currentCostAtomInfos, [¤tCost](const GringoOutputProcessor::CurrentCostAtomArguments& arguments) { // currentCost = arguments.currentCost; // }); // node->setCurrentCost(currentCost); node->setCurrentCost(node->getItems().size()); // }}} // Possibly update cost of root {{{ itemTree->getNode()->setCost(std::min(itemTree->getNode()->getCost(), cost)); // }}} } // Add node to item tree {{{ //ItemTree::Children::const_iterator newChild = itemTree->addChildAndMerge(ItemTree::ChildPtr(new ItemTree(std::move(node)))); newestRow = itemTree->costChangeAfterAddChildAndMerge(ItemTree::ChildPtr(new ItemTree(std::move(node)))); // }}} //if(newChild != itemTree->getChildren().end()) // newestRow = newChild; }