70 Graph<std::string> variableGraph = Graph<std::string>();
71 std::set<std::string> ruleVariables;
76 variableGraph.insert(var.getName());
77 ruleVariables.insert(var.getName());
84 std::vector<Literal*> literalsToConsider = clause.getBodyLiterals();
85 literalsToConsider.push_back(clause.getHead());
87 for (Literal* clauseLiteral : literalsToConsider) {
88 std::set<std::string> literalVariables;
92 [&](
const ast::Variable& var) { literalVariables.insert(var.getName()); });
95 if (literalVariables.size() > 1) {
96 std::string firstVariable = *literalVariables.begin();
97 literalVariables.erase(literalVariables.begin());
100 for (
const std::string& var : literalVariables) {
101 variableGraph.insert(firstVariable, var);
102 variableGraph.insert(var, firstVariable);
108 std::set<std::string> seenNodes;
111 std::set<std::string> headComponent;
113 *clause.getHead(), [&](
const ast::Variable& var) { headComponent.insert(var.getName()); });
115 if (!headComponent.empty()) {
116 variableGraph.visitDepthFirst(*headComponent.begin(), [&](
const std::string& var) {
117 headComponent.insert(var);
118 seenNodes.insert(var);
123 std::set<std::set<std::string>> connectedComponents;
125 for (std::string var : ruleVariables) {
126 if (seenNodes.find(var) != seenNodes.end()) {
132 std::set<std::string> component;
133 variableGraph.visitDepthFirst(var, [&](
const std::string& child) {
134 component.insert(child);
135 seenNodes.insert(child);
137 connectedComponents.insert(component);
140 if (connectedComponents.empty()) {
147 std::vector<Atom*> replacementAtoms;
150 for (
const std::set<std::string>& component : connectedComponents) {
152 static int disconnectedCount = 0;
153 std::stringstream nextName;
154 nextName <<
"+disconnected" << disconnectedCount;
155 QualifiedName newRelationName = nextName.str();
160 auto newRelation = mk<Relation>();
161 newRelation->setQualifiedName(newRelationName);
162 program.addRelation(std::move(newRelation));
164 auto* disconnectedClause =
new Clause();
165 disconnectedClause->setSrcLoc(clause.getSrcLoc());
166 disconnectedClause->setHead(mk<Atom>(newRelationName));
169 std::vector<Literal*> associatedLiterals;
170 for (Literal* bodyLiteral : clause.getBodyLiterals()) {
171 bool associated =
false;
173 if (component.find(var.getName()) != component.end()) {
183 replacementAtoms.push_back(
new Atom(newRelationName));
186 clausesToAdd.push_back(disconnectedClause);
191 auto* replacementClause =
new Clause();
192 replacementClause->setSrcLoc(clause.getSrcLoc());
196 for (Atom* newAtom : replacementAtoms) {
197 replacementClause->addToBody(Own<Literal>(newAtom));
201 for (Literal* bodyLiteral : clause.getBodyLiterals()) {
202 bool associated =
false;
203 bool hasVariables =
false;
206 if (headComponent.find(var.getName()) != headComponent.end()) {
210 if (associated || !hasVariables) {
216 clausesToRemove.push_back(&clause);
217 clausesToAdd.push_back(replacementClause);
221 for (Clause* newClause : clausesToAdd) {
222 program.addClause(Own<Clause>(newClause));
225 for (
const Clause* oldClause : clausesToRemove) {
226 program.removeClause(oldClause);