46 Program& program = translationUnit.getProgram();
47 std::set<std::pair<Aggregator*, Clause*>> pairs;
51 std::set<const Aggregator*> innerAggregates;
54 if (agg != innerAgg) {
55 innerAggregates.insert(&innerAgg);
64 if (innerAggregates.find(&agg) != innerAggregates.end()) {
74 auto* foundAggregate =
const_cast<Aggregator*
>(&agg);
75 auto* foundClause =
const_cast<Clause*
>(&clause);
76 pairs.insert(std::make_pair(foundAggregate, foundClause));
79 for (
auto pair : pairs) {
82 Clause* clause = pair.second;
85 auto aggRel = mk<Relation>();
86 auto aggHead = mk<Atom>();
87 auto aggClause = mk<Clause>();
90 aggRel->setQualifiedName(aggRelName);
91 aggHead->setQualifiedName(aggRelName);
95 auto variable = mk<ast::Variable>(variableName);
99 aggRel->addAttribute(mk<Attribute>(variableName,
"number"));
104 auto equalityLiteral = mk<BinaryConstraint>(
107 aggClause->addToBody(std::move(equalityLiteral));
108 program.addRelation(std::move(aggRel));
109 program.addClause(std::move(aggClause));
113 struct replaceAggregate :
public NodeMapper {
114 const Aggregator& aggregate;
117 : aggregate(aggregate), variable(
std::move(variable)) {}
118 Own<Node> operator()(Own<Node> node)
const override {
119 if (
auto* current =
dynamic_cast<Aggregator*
>(node.get())) {
120 if (*current == aggregate) {
122 assert(replacement !=
nullptr);
130 replaceAggregate update(*aggregate, std::move(variable));
131 clause->apply(update);
132 clause->addToBody(std::move(aggHead));
134 return pairs.size() > 0;
138 const TranslationUnit& tu,
const Aggregator& agg,
const Clause& clause) {
142 return injectedVariables.empty();