@@ -70,6 +70,8 @@ bool PartitionBodyLiteralsTransformer::transform(TranslationUnit& translationUni
7070 Graph<std::string> variableGraph = Graph<std::string>();
7171 std::set<std::string> ruleVariables;
7272
73+ const bool isSubsumption = isA<SubsumptiveClause>(clause);
74+
7375 // Add in the nodes
7476 // The nodes of G are the variables in the rule
7577 visit (clause, [&](const ast::Variable& var) {
@@ -110,6 +112,26 @@ bool PartitionBodyLiteralsTransformer::transform(TranslationUnit& translationUni
110112 std::set<std::string> headComponent;
111113 visit (*clause.getHead (), [&](const ast::Variable& var) { headComponent.insert (var.getName ()); });
112114
115+ if (isSubsumption) {
116+ // this works because subsumptive clause first two literals are the least and greatest atoms
117+ // of the original clause's head: `A(least, ... ) <= A(greatest, ...) :- ...`.
118+ std::set<std::string> leastAtomVariables;
119+ std::set<std::string> greatestAtomVariables;
120+ visit (literalsToConsider[0 ],
121+ [&](const ast::Variable& var) { leastAtomVariables.insert (var.getName ()); });
122+ visit (literalsToConsider[1 ],
123+ [&](const ast::Variable& var) { greatestAtomVariables.insert (var.getName ()); });
124+ // Create edge between any couple of variables taken respectively from the least and greatest
125+ // atoms: `least <-> greatest`, since in the previous step of the algorithm we already linked
126+ // variables within each atom.
127+ if (!(leastAtomVariables.empty () || greatestAtomVariables.empty ())) {
128+ const auto vL = *leastAtomVariables.begin ();
129+ const auto vG = *greatestAtomVariables.begin ();
130+ variableGraph.insert (vL, vG);
131+ variableGraph.insert (vG, vL);
132+ }
133+ }
134+
113135 if (!headComponent.empty ()) {
114136 variableGraph.visit (*headComponent.begin (), [&](const std::string& var) {
115137 headComponent.insert (var);
@@ -181,10 +203,17 @@ bool PartitionBodyLiteralsTransformer::transform(TranslationUnit& translationUni
181203 clausesToAdd.push_back (std::move (disconnectedClause));
182204 }
183205
184- // Create the replacement clause
185- // a(x) <- b(x), c(y), d(z). --> a(x) <- newrel0(), newrel1(), b(x).
186- auto replacementClause =
187- mk<Clause>(clone (clause.getHead ()), std::move (replacementAtoms), nullptr , clause.getSrcLoc ());
206+ // Create the replacement clause. The original literals must appear first and in order to
207+ // satisfy the SubsumptiveClause invariants.
208+ //
209+ // `a(x) <- b(x), c(y), d(z). --> a(x) <- b(x), newrel0(), newrel1().`
210+ Clause* replacementClause;
211+ if (isSubsumption) {
212+ replacementClause =
213+ new SubsumptiveClause (clone (clause.getHead ()), {}, nullptr , clause.getSrcLoc ());
214+ } else {
215+ replacementClause = new Clause (clone (clause.getHead ()), {}, nullptr , clause.getSrcLoc ());
216+ }
188217
189218 // Add the remaining body literals to the clause
190219 for (Literal* bodyLiteral : clause.getBodyLiterals ()) {
@@ -201,9 +230,11 @@ bool PartitionBodyLiteralsTransformer::transform(TranslationUnit& translationUni
201230 }
202231 }
203232
233+ replacementClause->addToBody (std::move (replacementAtoms));
234+
204235 // Replace the old clause with the new one
205236 clausesToRemove.push_back (&clause);
206- clausesToAdd.push_back (std::move (replacementClause));
237+ clausesToAdd.push_back (std::unique_ptr<Clause> (replacementClause));
207238 });
208239
209240 // Adjust the program
0 commit comments