Esempio n. 1
0
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;
}
Esempio n. 2
0
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, [&currentCost](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;
}
Esempio n. 3
0
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;
}