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;
}
Exemple #2
0
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;
}