Search in sources :

Example 1 with AggregateLiteral

use of at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral in project Alpha by alpha-asp.

the class ParserTest method cardinalityAggregate.

@Test
public void cardinalityAggregate() {
    ASPCore2Program parsedProgram = parser.parse("num(K) :-  K <= #count {X,Y,Z : p(X,Y,Z) }, dom(K).");
    Optional<Literal> optionalBodyElement = parsedProgram.getRules().get(0).getBody().stream().filter((lit) -> lit instanceof AggregateLiteral).findFirst();
    assertTrue(optionalBodyElement.isPresent());
    Literal bodyElement = optionalBodyElement.get();
    AggregateLiteral parsedAggregate = (AggregateLiteral) bodyElement;
    VariableTerm x = Terms.newVariable("X");
    VariableTerm y = Terms.newVariable("Y");
    VariableTerm z = Terms.newVariable("Z");
    List<Term> basicTerms = Arrays.asList(x, y, z);
    AggregateAtom.AggregateElement aggregateElement = Atoms.newAggregateElement(basicTerms, Collections.singletonList(Atoms.newBasicAtom(Predicates.getPredicate("p", 3), x, y, z).toLiteral()));
    AggregateAtom expectedAggregate = Atoms.newAggregateAtom(ComparisonOperators.LE, Terms.newVariable("K"), null, null, AggregateAtom.AggregateFunctionSymbol.COUNT, Collections.singletonList(aggregateElement));
    assertEquals(expectedAggregate, parsedAggregate.getAtom());
}
Also used : Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) Arrays(java.util.Arrays) AggregateAtom(at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom) Literal(at.ac.tuwien.kr.alpha.api.programs.literals.Literal) IntervalTerm(at.ac.tuwien.kr.alpha.commons.terms.IntervalTerm) InlineDirectives(at.ac.tuwien.kr.alpha.api.programs.InlineDirectives) Terms(at.ac.tuwien.kr.alpha.commons.terms.Terms) CharStreams(org.antlr.v4.runtime.CharStreams) CharStream(org.antlr.v4.runtime.CharStream) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) AggregateLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Term(at.ac.tuwien.kr.alpha.api.terms.Term) ReadableByteChannel(java.nio.channels.ReadableByteChannel) Atom(at.ac.tuwien.kr.alpha.api.programs.atoms.Atom) ChoiceHead(at.ac.tuwien.kr.alpha.api.rules.heads.ChoiceHead) IOException(java.io.IOException) Atoms(at.ac.tuwien.kr.alpha.commons.atoms.Atoms) Test(org.junit.jupiter.api.Test) VariableTerm(at.ac.tuwien.kr.alpha.api.terms.VariableTerm) List(java.util.List) Predicates(at.ac.tuwien.kr.alpha.commons.Predicates) Stream(java.util.stream.Stream) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) ASPCore2Program(at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program) Util(at.ac.tuwien.kr.alpha.commons.util.Util) Optional(java.util.Optional) Collections(java.util.Collections) FunctionTerm(at.ac.tuwien.kr.alpha.api.terms.FunctionTerm) ComparisonOperators(at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators) ASPCore2Program(at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program) AggregateLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral) Literal(at.ac.tuwien.kr.alpha.api.programs.literals.Literal) AggregateLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral) VariableTerm(at.ac.tuwien.kr.alpha.api.terms.VariableTerm) IntervalTerm(at.ac.tuwien.kr.alpha.commons.terms.IntervalTerm) Term(at.ac.tuwien.kr.alpha.api.terms.Term) VariableTerm(at.ac.tuwien.kr.alpha.api.terms.VariableTerm) FunctionTerm(at.ac.tuwien.kr.alpha.api.terms.FunctionTerm) AggregateAtom(at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom) Test(org.junit.jupiter.api.Test)

Example 2 with AggregateLiteral

use of at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral in project Alpha by alpha-asp.

the class AggregateOperatorNormalization method rewriteAggregateOperator.

private static List<Literal> rewriteAggregateOperator(AggregateLiteral lit) {
    AggregateAtom atom = lit.getAtom();
    if (atom.getLowerBoundOperator() == null && atom.getUpperBoundOperator() != null) {
        return rewriteAggregateOperator(convertToLeftHandComparison(lit));
    }
    if (lit.getAtom().getAggregateFunction() == AggregateFunctionSymbol.MIN || lit.getAtom().getAggregateFunction() == AggregateFunctionSymbol.MAX) {
        // No operator normalization needed for #min/#max aggregates.
        return Collections.singletonList(lit);
    }
    if (atom.getLowerBoundOperator().equals(ComparisonOperators.EQ) || atom.getLowerBoundOperator().equals(ComparisonOperators.LE)) {
        // Nothing to do for operator "=" or "<=".
        return Collections.singletonList(lit);
    } else {
        List<Literal> retVal = new ArrayList<>();
        VariableTerm decrementedBound;
        ComparisonOperator lowerBoundOp = atom.getLowerBoundOperator();
        if (lowerBoundOp.equals(ComparisonOperators.LT)) {
            decrementedBound = Terms.newAnonymousVariable();
            retVal.add(createLowerBoundedAggregateLiteral(ComparisonOperators.LE, decrementedBound, atom, !lit.isNegated()));
            retVal.add(createPlusOneTerm(atom.getLowerBoundTerm(), decrementedBound));
        } else if (lowerBoundOp.equals(ComparisonOperators.NE)) {
            retVal.add(createLowerBoundedAggregateLiteral(ComparisonOperators.EQ, atom.getLowerBoundTerm(), atom, lit.isNegated()));
        } else if (lowerBoundOp.equals(ComparisonOperators.GT)) {
            retVal.add(createLowerBoundedAggregateLiteral(ComparisonOperators.LE, atom.getLowerBoundTerm(), atom, lit.isNegated()));
        } else if (lowerBoundOp.equals(ComparisonOperators.GE)) {
            decrementedBound = Terms.newAnonymousVariable();
            retVal.add(createLowerBoundedAggregateLiteral(ComparisonOperators.LE, decrementedBound, atom, lit.isNegated()));
            retVal.add(createPlusOneTerm(atom.getLowerBoundTerm(), decrementedBound));
        } else {
            throw new IllegalStateException("No operator rewriting logic available for literal: " + lit);
        }
        return retVal;
    }
}
Also used : ComparisonOperator(at.ac.tuwien.kr.alpha.api.ComparisonOperator) Literal(at.ac.tuwien.kr.alpha.api.programs.literals.Literal) AggregateLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral) ArrayList(java.util.ArrayList) VariableTerm(at.ac.tuwien.kr.alpha.api.terms.VariableTerm) AggregateAtom(at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom)

Example 3 with AggregateLiteral

use of at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral in project Alpha by alpha-asp.

the class AggregateLiteralSplitting method splitAggregatesInRule.

private static List<Rule<Head>> splitAggregatesInRule(Rule<Head> sourceRule) {
    // Rule contains some aggregates that need splitting.
    // Aggregates may require splitting in two literals, or in two rules.
    List<Literal> commonBodyLiterals = new ArrayList<>();
    List<Literal> twoLiteralsSplitAggregates = new ArrayList<>();
    List<ImmutablePair<Literal, Literal>> twoRulesSplitAggregates = new ArrayList<>();
    // First, sort literals of the rule and also compute splitting.
    for (Literal literal : sourceRule.getBody()) {
        if (literal instanceof AggregateLiteral && shouldRewrite((AggregateLiteral) literal)) {
            splitCombinedAggregateLiteral(literal, twoLiteralsSplitAggregates, twoRulesSplitAggregates);
        } else {
            // Literal is no aggregate that needs splitting.
            commonBodyLiterals.add(literal);
        }
    }
    // Second, compute rule bodies of splitting result.
    List<Literal> commonBody = new ArrayList<>(commonBodyLiterals);
    commonBody.addAll(twoLiteralsSplitAggregates);
    List<List<Literal>> rewrittenBodies = new ArrayList<>();
    // Initialize list of rules with the common body.
    rewrittenBodies.add(commonBody);
    // for each of the n pairs in twoRulesSplitAggregates we duplicate the list of rewritten bodies.
    for (ImmutablePair<Literal, Literal> ruleSplitAggregate : twoRulesSplitAggregates) {
        int numBodiesBeforeDuplication = rewrittenBodies.size();
        for (int i = 0; i < numBodiesBeforeDuplication; i++) {
            List<Literal> originalBody = rewrittenBodies.get(i);
            List<Literal> duplicatedBody = new ArrayList<>(originalBody);
            // Extend bodies of original and duplicate with splitting results.
            originalBody.add(ruleSplitAggregate.left);
            duplicatedBody.add(ruleSplitAggregate.right);
            rewrittenBodies.add(duplicatedBody);
        }
    }
    // Third, turn computed bodies into rules again.
    List<Rule<Head>> rewrittenRules = new ArrayList<>();
    for (List<Literal> rewrittenBody : rewrittenBodies) {
        rewrittenRules.add(new BasicRule(sourceRule.getHead(), rewrittenBody));
    }
    return rewrittenRules;
}
Also used : BasicRule(at.ac.tuwien.kr.alpha.core.rules.BasicRule) ArrayList(java.util.ArrayList) ImmutablePair(org.apache.commons.lang3.tuple.ImmutablePair) AggregateLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral) Literal(at.ac.tuwien.kr.alpha.api.programs.literals.Literal) AggregateLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral) ArrayList(java.util.ArrayList) List(java.util.List) Rule(at.ac.tuwien.kr.alpha.api.rules.Rule) BasicRule(at.ac.tuwien.kr.alpha.core.rules.BasicRule)

Example 4 with AggregateLiteral

use of at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral in project Alpha by alpha-asp.

the class AggregateRewriting method rewriteRulesWithAggregates.

/**
 * Transforms (restricted) aggregate literals of format "VAR OP #AGG_FN{...}" into literals of format
 * "<result_predicate>(ARGS, VAR)" where ARGS is a function term wrapping the aggregate's global variables.
 *
 * @param ctx the {@link AggregateRewritingContext} containing information about all aggregates.
 * @return for each rule, its rewritten version where aggregates are replaced with output atoms of the encoding.
 */
private static List<Rule<Head>> rewriteRulesWithAggregates(AggregateRewritingContext ctx) {
    List<Rule<Head>> rewrittenRules = new ArrayList<>();
    for (Rule<Head> rule : ctx.getRulesWithAggregates()) {
        List<Literal> rewrittenBody = new ArrayList<>();
        for (Literal lit : rule.getBody()) {
            if (lit instanceof AggregateLiteral) {
                AggregateInfo aggregateInfo = ctx.getAggregateInfo((AggregateLiteral) lit);
                rewrittenBody.add(Literals.fromAtom(aggregateInfo.getOutputAtom(), !lit.isNegated()));
            } else {
                rewrittenBody.add(lit);
            }
        }
        rewrittenRules.add(new BasicRule(rule.getHead(), rewrittenBody));
    }
    return rewrittenRules;
}
Also used : BasicRule(at.ac.tuwien.kr.alpha.core.rules.BasicRule) Head(at.ac.tuwien.kr.alpha.api.rules.heads.Head) AggregateLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral) Literal(at.ac.tuwien.kr.alpha.api.programs.literals.Literal) AggregateLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral) ArrayList(java.util.ArrayList) Rule(at.ac.tuwien.kr.alpha.api.rules.Rule) BasicRule(at.ac.tuwien.kr.alpha.core.rules.BasicRule) AggregateInfo(at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.AggregateRewritingContext.AggregateInfo)

Example 5 with AggregateLiteral

use of at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral in project Alpha by alpha-asp.

the class AggregateRewritingRuleAnalysis method findGlobalVariablesPerAggregate.

private void findGlobalVariablesPerAggregate() {
    // First, compute all global variables, that is all variables occurring in a rule except those occurring
    // inside aggregate elements.
    Set<VariableTerm> globalVariables = new HashSet<>();
    if (!rule.isConstraint()) {
        // Head must be normal at this point.
        NormalHead head = (NormalHead) rule.getHead();
        globalVariables.addAll(head.getAtom().getOccurringVariables());
    }
    for (Literal literal : rule.getBody()) {
        if (literal instanceof AggregateLiteral) {
            aggregatesInRule.add((AggregateLiteral) literal);
            AggregateAtom aggregateAtom = (AggregateAtom) literal.getAtom();
            // All variables in the bounds of an aggregate are also global variables.
            // Note that at this point, only lower bounds appear in aggregates.
            globalVariables.addAll(aggregateAtom.getLowerBoundTerm().getOccurringVariables());
        } else {
            globalVariables.addAll(literal.getOccurringVariables());
        }
    }
    // Second, compute for each aggregate those of its variables that are global.
    for (AggregateLiteral aggregateLiteral : aggregatesInRule) {
        Set<VariableTerm> globalVariablesInAggregate = new HashSet<>();
        for (VariableTerm aggregateVariable : aggregateLiteral.getAtom().getAggregateVariables()) {
            if (globalVariables.contains(aggregateVariable)) {
                globalVariablesInAggregate.add(aggregateVariable);
            }
        }
        globalVariablesPerAggregate.put(aggregateLiteral, globalVariablesInAggregate);
    }
}
Also used : NormalHead(at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead) AggregateLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral) Literal(at.ac.tuwien.kr.alpha.api.programs.literals.Literal) AggregateLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral) VariableTerm(at.ac.tuwien.kr.alpha.api.terms.VariableTerm) AggregateAtom(at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom) HashSet(java.util.HashSet)

Aggregations

AggregateLiteral (at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral)18 Literal (at.ac.tuwien.kr.alpha.api.programs.literals.Literal)15 VariableTerm (at.ac.tuwien.kr.alpha.api.terms.VariableTerm)7 Test (org.junit.jupiter.api.Test)7 AggregateAtom (at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom)4 Term (at.ac.tuwien.kr.alpha.api.terms.Term)4 ArrayList (java.util.ArrayList)4 Rule (at.ac.tuwien.kr.alpha.api.rules.Rule)3 BasicRule (at.ac.tuwien.kr.alpha.core.rules.BasicRule)3 HashSet (java.util.HashSet)3 ASPCore2Program (at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program)2 AggregateElement (at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateElement)2 ComparisonLiteral (at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral)2 Head (at.ac.tuwien.kr.alpha.api.rules.heads.Head)2 List (java.util.List)2 Map (java.util.Map)2 Set (java.util.Set)2 ComparisonOperator (at.ac.tuwien.kr.alpha.api.ComparisonOperator)1 InlineDirectives (at.ac.tuwien.kr.alpha.api.programs.InlineDirectives)1 Atom (at.ac.tuwien.kr.alpha.api.programs.atoms.Atom)1