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();