Search in sources :

Example 1 with Rule

use of at.ac.tuwien.kr.alpha.api.rules.Rule 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 2 with Rule

use of at.ac.tuwien.kr.alpha.api.rules.Rule 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 3 with Rule

use of at.ac.tuwien.kr.alpha.api.rules.Rule in project Alpha by alpha-asp.

the class LiteralBindingNonBindingVariablesTest method testPositiveExternalLiteral.

@Test
public void testPositiveExternalLiteral() {
    externals.put("ext", new IntPredicateInterpretation(i -> i > 0));
    Rule<Head> rule = parser.parse("p(X) :- q(Y), &ext[Y](X).", externals).getRules().get(0);
    Literal literal = rule.getBody().stream().filter((lit) -> lit.getPredicate().getName().equals("ext")).findFirst().get();
    assertEquals(false, literal.isNegated());
    expectVariables(literal.getBindingVariables(), "X");
    expectVariables(literal.getNonBindingVariables(), "Y");
}
Also used : Arrays(java.util.Arrays) Rule(at.ac.tuwien.kr.alpha.api.rules.Rule) ProgramParser(at.ac.tuwien.kr.alpha.api.programs.ProgramParser) Collection(java.util.Collection) Atom(at.ac.tuwien.kr.alpha.api.programs.atoms.Atom) Set(java.util.Set) HashMap(java.util.HashMap) Literal(at.ac.tuwien.kr.alpha.api.programs.literals.Literal) Disabled(org.junit.jupiter.api.Disabled) Collectors(java.util.stream.Collectors) Test(org.junit.jupiter.api.Test) Head(at.ac.tuwien.kr.alpha.api.rules.heads.Head) VariableTerm(at.ac.tuwien.kr.alpha.api.terms.VariableTerm) IntPredicateInterpretation(at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.IntPredicateInterpretation) PredicateInterpretation(at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation) ProgramParserImpl(at.ac.tuwien.kr.alpha.core.parser.ProgramParserImpl) Map(java.util.Map) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) ComparisonOperators(at.ac.tuwien.kr.alpha.commons.comparisons.ComparisonOperators) Head(at.ac.tuwien.kr.alpha.api.rules.heads.Head) IntPredicateInterpretation(at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.IntPredicateInterpretation) Literal(at.ac.tuwien.kr.alpha.api.programs.literals.Literal) Test(org.junit.jupiter.api.Test)

Example 4 with Rule

use of at.ac.tuwien.kr.alpha.api.rules.Rule in project Alpha by alpha-asp.

the class RuleToStringTest method parseSingleRule.

private Rule<Head> parseSingleRule(String rule) {
    ASPCore2Program program = parser.parse(rule);
    List<Rule<Head>> rules = program.getRules();
    assertEquals(1, rules.size(), "Number of rules");
    return rules.get(0);
}
Also used : ASPCore2Program(at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program) Rule(at.ac.tuwien.kr.alpha.api.rules.Rule) CompiledRule(at.ac.tuwien.kr.alpha.core.rules.CompiledRule) BasicRule(at.ac.tuwien.kr.alpha.core.rules.BasicRule) InternalRule(at.ac.tuwien.kr.alpha.core.rules.InternalRule)

Example 5 with Rule

use of at.ac.tuwien.kr.alpha.api.rules.Rule in project Alpha by alpha-asp.

the class AggregateRewriting method apply.

/**
 * Rewrites all {@link AggregateLiteral}s in the given program.
 * The transformation workflow is split into a preprocessing- and an encoding phase.
 * During preprocessing, all aggregate literals with two comparison operators are split into two aggregate literals with
 * only a "lower bound" term and operator. After literal splitting, operators are normalized, i.e. all "count" and "sum"
 * literals are rewritten to use either "<=" or "=" as comparison operator.
 *
 * Rules containing {@link AggregateLiteral}s are registered in an {@link AggregateRewritingContext} during
 * preprocessing. After preprocessing, for each rule in the context, aggregate literals in the rule body are substituted
 * with normal literals of form "$id$_aggregate_result(...)". For each literal substituted this way, a set of rules
 * deriving the result literal is added that is semantically equivalent to the replaced aggregate literal.
 */
@Override
public ASPCore2Program apply(ASPCore2Program inputProgram) {
    AggregateRewritingContext ctx = new AggregateRewritingContext();
    List<Rule<Head>> outputRules = new ArrayList<>();
    for (Rule<Head> inputRule : inputProgram.getRules()) {
        // Split literals with two operators.
        for (Rule<Head> splitRule : AggregateLiteralSplitting.split(inputRule)) {
            // Normalize operators on aggregate literals after splitting.
            Rule<Head> operatorNormalizedRule = AggregateOperatorNormalization.normalize(splitRule);
            boolean hasAggregate = ctx.registerRule(operatorNormalizedRule);
            // Only keep rules without aggregates. The ones with aggregates are registered in the context and taken care of later.
            if (!hasAggregate) {
                outputRules.add(operatorNormalizedRule);
            }
        }
    }
    // Substitute AggregateLiterals with generated result literals.
    outputRules.addAll(rewriteRulesWithAggregates(ctx));
    InputProgram.Builder resultBuilder = InputProgram.builder().addRules(outputRules).addFacts(inputProgram.getFacts()).addInlineDirectives(inputProgram.getInlineDirectives());
    // Add sub-programs deriving respective aggregate literals.
    for (Map.Entry<ImmutablePair<AggregateFunctionSymbol, ComparisonOperator>, Set<AggregateInfo>> aggToRewrite : ctx.getAggregateFunctionsToRewrite().entrySet()) {
        ImmutablePair<AggregateFunctionSymbol, ComparisonOperator> func = aggToRewrite.getKey();
        AbstractAggregateEncoder encoder = getEncoderForAggregateFunction(func.left, func.right);
        resultBuilder.accumulate(encoder.encodeAggregateLiterals(aggToRewrite.getValue()));
    }
    return resultBuilder.build();
}
Also used : AbstractAggregateEncoder(at.ac.tuwien.kr.alpha.core.programs.transformation.aggregates.encoders.AbstractAggregateEncoder) Head(at.ac.tuwien.kr.alpha.api.rules.heads.Head) ComparisonOperator(at.ac.tuwien.kr.alpha.api.ComparisonOperator) Set(java.util.Set) ArrayList(java.util.ArrayList) AggregateFunctionSymbol(at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol) ImmutablePair(org.apache.commons.lang3.tuple.ImmutablePair) Rule(at.ac.tuwien.kr.alpha.api.rules.Rule) BasicRule(at.ac.tuwien.kr.alpha.core.rules.BasicRule) Map(java.util.Map) InputProgram(at.ac.tuwien.kr.alpha.core.programs.InputProgram)

Aggregations

Rule (at.ac.tuwien.kr.alpha.api.rules.Rule)9 BasicRule (at.ac.tuwien.kr.alpha.core.rules.BasicRule)8 ArrayList (java.util.ArrayList)7 Head (at.ac.tuwien.kr.alpha.api.rules.heads.Head)6 Literal (at.ac.tuwien.kr.alpha.api.programs.literals.Literal)5 InputProgram (at.ac.tuwien.kr.alpha.core.programs.InputProgram)4 AggregateLiteral (at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral)3 ASPCore2Program (at.ac.tuwien.kr.alpha.api.programs.ASPCore2Program)2 Predicate (at.ac.tuwien.kr.alpha.api.programs.Predicate)2 Term (at.ac.tuwien.kr.alpha.api.terms.Term)2 VariableTerm (at.ac.tuwien.kr.alpha.api.terms.VariableTerm)2 Map (java.util.Map)2 Set (java.util.Set)2 ImmutablePair (org.apache.commons.lang3.tuple.ImmutablePair)2 ComparisonOperator (at.ac.tuwien.kr.alpha.api.ComparisonOperator)1 PredicateInterpretation (at.ac.tuwien.kr.alpha.api.common.fixedinterpretations.PredicateInterpretation)1 ProgramParser (at.ac.tuwien.kr.alpha.api.programs.ProgramParser)1 AggregateElement (at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateElement)1 AggregateFunctionSymbol (at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom.AggregateFunctionSymbol)1 Atom (at.ac.tuwien.kr.alpha.api.programs.atoms.Atom)1