use of at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral in project Alpha by alpha-asp.
the class AggregateLiteralSplitting method splitCombinedAggregateLiteral.
private static void splitCombinedAggregateLiteral(Literal literal, List<Literal> twoLiteralsSplitAggregates, List<ImmutablePair<Literal, Literal>> twoRulesSplitAggregates) {
AggregateLiteral aggLit = (AggregateLiteral) literal;
ImmutablePair<AggregateAtom, AggregateAtom> splitAggregate = splitCombinedAggregateAtom(aggLit.getAtom());
if (literal.isNegated()) {
// Negated aggregate require splitting in two rules.
twoRulesSplitAggregates.add(new ImmutablePair<>(splitAggregate.left.toLiteral(false), splitAggregate.right.toLiteral(false)));
} else {
// Positive aggregate requires two literals in the body.
twoLiteralsSplitAggregates.add(splitAggregate.left.toLiteral(true));
twoLiteralsSplitAggregates.add(splitAggregate.right.toLiteral(true));
}
}
use of at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral in project Alpha by alpha-asp.
the class AbstractAggregateEncoder method encodeAggregateLiteral.
/**
* Encodes the aggregate literal referenced by the given {@link AggregateInfo}.
*
* @param aggregateToEncode
* @return
*/
public ASPCore2Program encodeAggregateLiteral(AggregateInfo aggregateToEncode) {
AggregateLiteral literalToEncode = aggregateToEncode.getLiteral();
if (literalToEncode.getAtom().getAggregateFunction() != this.aggregateFunctionToEncode) {
throw new IllegalArgumentException("Encoder " + this.getClass().getSimpleName() + " cannot encode aggregate function " + literalToEncode.getAtom().getAggregateFunction());
}
if (!this.acceptedOperators.contains(literalToEncode.getAtom().getLowerBoundOperator())) {
throw new IllegalArgumentException("Encoder " + this.getClass().getSimpleName() + " cannot encode aggregate function " + literalToEncode.getAtom().getAggregateFunction() + " with operator " + literalToEncode.getAtom().getLowerBoundOperator());
}
String aggregateId = aggregateToEncode.getId();
ASPCore2Program literalEncoding = PredicateInternalizer.makePrefixedPredicatesInternal(encodeAggregateResult(aggregateToEncode), aggregateId);
List<Rule<Head>> elementEncodingRules = new ArrayList<>();
for (AggregateElement elementToEncode : literalToEncode.getAtom().getAggregateElements()) {
Rule<Head> elementRule = encodeAggregateElement(aggregateToEncode, elementToEncode);
elementEncodingRules.add(PredicateInternalizer.makePrefixedPredicatesInternal(elementRule, aggregateId));
}
return new InputProgram(ListUtils.union(literalEncoding.getRules(), elementEncodingRules), literalEncoding.getFacts(), new InlineDirectivesImpl());
}
use of at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral in project Alpha by alpha-asp.
the class AggregateRewritingRuleAnalysis method findBindingLiterals.
/**
* Recursively looks for literals in <code>searchScope</code> that bind the variables in the set
* <code>varsToBind</code>, i.e. any literal lit that has any variable var in question in its
* <code>bindingVariables</code> (i.e. lit assigns a value to var). Found binding literals are added to the set
* <code>boundSoFar</code>. If a literal has any of the desired variables as a binding variable, but also has other
* non-binding variables, the literals binding these are added to the set of desired variables for the next recursive
* call. Since {@link AggregateLiteral}s cannot report their non-binding variables by themselves, this method also needs
* a map of all aggregate literals and their global variables within the search scope.
*/
// Note: This algorithm has potentially exponential time complexity. Tuning potential definitely exists, but
// performance optimization seems non-trivial.
private static void findBindingLiterals(Set<VariableTerm> varsToBind, Set<VariableTerm> varsBoundSoFar, Set<Literal> foundSoFar, Set<Literal> searchScope, Map<AggregateLiteral, Set<VariableTerm>> aggregatesWithGlobalVars) {
int newlyBoundVars = 0;
Set<VariableTerm> furtherVarsToBind = new HashSet<>();
for (VariableTerm varToBind : varsToBind) {
for (Literal lit : searchScope) {
Set<VariableTerm> bindingVars = lit.getBindingVariables();
Set<VariableTerm> nonBindingVars = (lit instanceof AggregateLiteral) ? aggregatesWithGlobalVars.get((AggregateLiteral) lit) : lit.getNonBindingVariables();
if (bindingVars.contains(varToBind)) {
varsBoundSoFar.add(varToBind);
foundSoFar.add(lit);
newlyBoundVars++;
for (VariableTerm nonBindingVar : nonBindingVars) {
if (!varsBoundSoFar.contains(nonBindingVar)) {
furtherVarsToBind.add(nonBindingVar);
}
}
}
}
}
if (newlyBoundVars == 0 && !varsToBind.isEmpty()) {
// screaming than producing a stack overflow ;-)
throw new IllegalStateException("Couldn't find any literals binding variables: " + varsToBind + " in search scope " + searchScope);
}
if (!furtherVarsToBind.isEmpty()) {
// As long as we find variables we still need to bind, repeat with the new set of variables to bind.
findBindingLiterals(furtherVarsToBind, varsBoundSoFar, foundSoFar, searchScope, aggregatesWithGlobalVars);
}
}
Aggregations