28     Program& program = translationUnit.getProgram();
 
   30     struct AggregateWithWitnesses {
 
   33         std::set<std::string> witnesses;
 
   35         AggregateWithWitnesses(
Aggregator* agg, 
Clause* clause, std::set<std::string> witnesses)
 
   36                 : aggregate(agg), originatingClause(clause), witnesses(
std::move(witnesses)) {}
 
   39     std::vector<AggregateWithWitnesses> aggregatesToFix;
 
   46                 if (agg == innerAgg) {
 
   50                 for (
const auto& witness : innerWitnesses) {
 
   51                     witnessVariables.erase(witness);
 
   54             if (witnessVariables.empty()) {
 
   57             AggregateWithWitnesses instance(
 
   58                     const_cast<Aggregator*
>(&agg), 
const_cast<Clause*
>(&clause), witnessVariables);
 
   59             aggregatesToFix.push_back(instance);
 
   63     for (
struct AggregateWithWitnesses& aggregateToFix : aggregatesToFix) {
 
   64         Aggregator* agg = aggregateToFix.aggregate;
 
   65         Clause* clause = aggregateToFix.originatingClause;
 
   66         std::set<std::string> witnesses = aggregateToFix.witnesses;
 
   71         std::vector<std::unique_ptr<Literal>> aggregateLiterals;
 
   72         for (
const auto& literal : agg->getBodyLiterals()) {
 
   79         std::map<std::string, std::string> newWitnessVariableName;
 
   80         for (std::string witness : witnesses) {
 
   84             if (witnesses.find(var.getName()) != witnesses.end()) {
 
   86                 const_cast<Variable&>(var).setName(newWitnessVariableName[var.getName()]);
 
   91         struct TargetVariableReplacer : 
public NodeMapper {
 
   92             Aggregator* aggregate;
 
   93             std::string targetVariable;
 
   94             TargetVariableReplacer(Aggregator* agg, std::string target)
 
   95                     : aggregate(agg), targetVariable(
std::move(target)) {}
 
   96             std::unique_ptr<Node> operator()(std::unique_ptr<Node> node)
 const override {
 
   97                 if (
auto* variable = 
dynamic_cast<Variable*
>(node.get())) {
 
   98                     if (variable->getName() == targetVariable) {
 
  107         const auto* targetVariable = 
dynamic_cast<const Variable*
>(agg->getTargetExpression());
 
  108         std::string targetVariableName = targetVariable->getName();
 
  109         TargetVariableReplacer replacer(agg, targetVariableName);
 
  110         for (std::unique_ptr<Literal>& literal : aggregateLiterals) {
 
  111             literal->apply(replacer);
 
  118     return !aggregatesToFix.empty();