Search in sources :

Example 1 with BasicRule

use of at.ac.tuwien.kr.alpha.core.rules.BasicRule 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 BasicRule

use of at.ac.tuwien.kr.alpha.core.rules.BasicRule 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 BasicRule

use of at.ac.tuwien.kr.alpha.core.rules.BasicRule in project Alpha by alpha-asp.

the class AlphaImplTest method withExternalSubtype.

@Test
public void withExternalSubtype() throws Exception {
    SubThingy thingy = new SubThingy();
    BasicRule rule = new BasicRule(Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate("p", 1), Terms.newConstant("x"))), singletonList(Literals.fromAtom(Atoms.newExternalAtom(Predicates.getPredicate("thinger", 1), new MethodPredicateInterpretation(this.getClass().getMethod("thinger", Thingy.class)), singletonList(Terms.newConstant(thingy)), emptyList()), true)));
    Alpha system = new AlphaImpl();
    InputProgram prog = new InputProgram(singletonList(rule), emptyList(), new InlineDirectivesImpl());
    Set<AnswerSet> actual = system.solve(prog).collect(Collectors.toSet());
    Set<AnswerSet> expected = new HashSet<>(singletonList(new AnswerSetBuilder().predicate("p").instance("x").build()));
    assertEquals(expected, actual);
}
Also used : BasicRule(at.ac.tuwien.kr.alpha.core.rules.BasicRule) AnswerSet(at.ac.tuwien.kr.alpha.api.AnswerSet) Alpha(at.ac.tuwien.kr.alpha.api.Alpha) MethodPredicateInterpretation(at.ac.tuwien.kr.alpha.core.common.fixedinterpretations.MethodPredicateInterpretation) AnswerSetBuilder(at.ac.tuwien.kr.alpha.commons.AnswerSetBuilder) InlineDirectivesImpl(at.ac.tuwien.kr.alpha.core.parser.InlineDirectivesImpl) InputProgram(at.ac.tuwien.kr.alpha.core.programs.InputProgram) HashSet(java.util.HashSet) Test(org.junit.jupiter.api.Test)

Example 4 with BasicRule

use of at.ac.tuwien.kr.alpha.core.rules.BasicRule in project Alpha by alpha-asp.

the class ChoiceHeadToNormal method apply.

@Override
public ASPCore2Program apply(ASPCore2Program inputProgram) {
    InputProgram.Builder programBuilder = InputProgram.builder();
    List<Rule<Head>> additionalRules = new ArrayList<>();
    List<Rule<Head>> srcRules = new ArrayList<>(inputProgram.getRules());
    Iterator<Rule<Head>> ruleIterator = srcRules.iterator();
    while (ruleIterator.hasNext()) {
        Rule<Head> rule = ruleIterator.next();
        Head ruleHead = rule.getHead();
        if (!(ruleHead instanceof ChoiceHead)) {
            // Rule is constraint or without choice in the head. Leave as is.
            continue;
        }
        // Remove this rule, as it will be transformed.
        ruleIterator.remove();
        ChoiceHead choiceHead = (ChoiceHead) ruleHead;
        // Choice rules with boundaries are not yet supported.
        if (choiceHead.getLowerBound() != null || choiceHead.getUpperBound() != null) {
            throw new UnsupportedOperationException("Found choice rule with bounds, which are not yet supported. Rule is: " + rule);
        }
        // Only rewrite rules with a choice in their head.
        for (ChoiceElement choiceElement : choiceHead.getChoiceElements()) {
            // Create two guessing rules for each choiceElement.
            // Construct common body to both rules.
            BasicAtom head = choiceElement.getChoiceAtom();
            List<Literal> ruleBody = new ArrayList<>(rule.getBody());
            ruleBody.addAll(choiceElement.getConditionLiterals());
            if (containsIntervalTerms(head)) {
                throw new RuntimeException("Program contains a choice rule with interval terms in its head. This is not supported (yet).");
            }
            // Construct head atom for the choice.
            Predicate headPredicate = head.getPredicate();
            Predicate negPredicate = Predicates.getPredicate(PREDICATE_NEGATION_PREFIX + headPredicate.getName(), headPredicate.getArity() + 1, true);
            List<Term> headTerms = new ArrayList<>(head.getTerms());
            // FIXME: when introducing classical negation, this is 1 for classical positive atoms and 0 for
            headTerms.add(0, Terms.newConstant("1"));
            // classical negative atoms.
            BasicAtom negHead = Atoms.newBasicAtom(negPredicate, headTerms);
            // Construct two guessing rules.
            List<Literal> guessingRuleBodyWithNegHead = new ArrayList<>(ruleBody);
            guessingRuleBodyWithNegHead.add(Atoms.newBasicAtom(head.getPredicate(), head.getTerms()).toLiteral(false));
            additionalRules.add(new BasicRule(Heads.newNormalHead(negHead), guessingRuleBodyWithNegHead));
            List<Literal> guessingRuleBodyWithHead = new ArrayList<>(ruleBody);
            guessingRuleBodyWithHead.add(Atoms.newBasicAtom(negPredicate, headTerms).toLiteral(false));
            additionalRules.add(new BasicRule(Heads.newNormalHead(head), guessingRuleBodyWithHead));
        // TODO: when cardinality constraints are possible, process the boundaries by adding a constraint with a cardinality check.
        }
    }
    return programBuilder.addRules(srcRules).addRules(additionalRules).addFacts(inputProgram.getFacts()).addInlineDirectives(inputProgram.getInlineDirectives()).build();
}
Also used : BasicRule(at.ac.tuwien.kr.alpha.core.rules.BasicRule) ChoiceHead(at.ac.tuwien.kr.alpha.api.rules.heads.ChoiceHead) Head(at.ac.tuwien.kr.alpha.api.rules.heads.Head) ArrayList(java.util.ArrayList) Term(at.ac.tuwien.kr.alpha.api.terms.Term) IntervalTerm(at.ac.tuwien.kr.alpha.commons.terms.IntervalTerm) Predicate(at.ac.tuwien.kr.alpha.api.programs.Predicate) ChoiceElement(at.ac.tuwien.kr.alpha.api.rules.heads.ChoiceHead.ChoiceElement) ChoiceHead(at.ac.tuwien.kr.alpha.api.rules.heads.ChoiceHead) Literal(at.ac.tuwien.kr.alpha.api.programs.literals.Literal) Rule(at.ac.tuwien.kr.alpha.api.rules.Rule) BasicRule(at.ac.tuwien.kr.alpha.core.rules.BasicRule) BasicAtom(at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom) InputProgram(at.ac.tuwien.kr.alpha.core.programs.InputProgram)

Example 5 with BasicRule

use of at.ac.tuwien.kr.alpha.core.rules.BasicRule in project Alpha by alpha-asp.

the class PredicateInternalizer method makePrefixedPredicatesInternal.

public static Rule<Head> makePrefixedPredicatesInternal(Rule<Head> rule, String prefix) {
    Head newHead = null;
    if (rule.getHead() != null) {
        if (!(rule.getHead() instanceof NormalHead)) {
            throw new UnsupportedOperationException("Cannot make predicates in rules internal whose head is not normal.");
        }
        NormalHead head = (NormalHead) rule.getHead();
        if (head.getAtom().getPredicate().getName().startsWith(prefix)) {
            newHead = Heads.newNormalHead(makePredicateInternal(head.getAtom()));
        } else {
            newHead = head;
        }
    }
    List<Literal> newBody = new ArrayList<>();
    for (Literal bodyElement : rule.getBody()) {
        // Only rewrite BasicAtoms.
        if (bodyElement instanceof BasicLiteral) {
            if (bodyElement.getAtom().getPredicate().getName().startsWith(prefix)) {
                newBody.add(makePredicateInternal((BasicAtom) bodyElement.getAtom()).toLiteral(!bodyElement.isNegated()));
            } else {
                newBody.add(bodyElement);
            }
        } else {
            // Keep other body element as is.
            newBody.add(bodyElement);
        }
    }
    return new BasicRule(newHead, newBody);
}
Also used : BasicRule(at.ac.tuwien.kr.alpha.core.rules.BasicRule) BasicLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.BasicLiteral) Head(at.ac.tuwien.kr.alpha.api.rules.heads.Head) NormalHead(at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead) NormalHead(at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead) Literal(at.ac.tuwien.kr.alpha.api.programs.literals.Literal) BasicLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.BasicLiteral) ArrayList(java.util.ArrayList)

Aggregations

BasicRule (at.ac.tuwien.kr.alpha.core.rules.BasicRule)8 Literal (at.ac.tuwien.kr.alpha.api.programs.literals.Literal)7 ArrayList (java.util.ArrayList)7 Rule (at.ac.tuwien.kr.alpha.api.rules.Rule)4 Head (at.ac.tuwien.kr.alpha.api.rules.heads.Head)4 NormalHead (at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead)4 Term (at.ac.tuwien.kr.alpha.api.terms.Term)3 VariableTerm (at.ac.tuwien.kr.alpha.api.terms.VariableTerm)3 InputProgram (at.ac.tuwien.kr.alpha.core.programs.InputProgram)3 AggregateLiteral (at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral)2 BasicLiteral (at.ac.tuwien.kr.alpha.api.programs.literals.BasicLiteral)2 ComparisonLiteral (at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral)2 HashSet (java.util.HashSet)2 Alpha (at.ac.tuwien.kr.alpha.api.Alpha)1 AnswerSet (at.ac.tuwien.kr.alpha.api.AnswerSet)1 ComparisonOperator (at.ac.tuwien.kr.alpha.api.ComparisonOperator)1 Predicate (at.ac.tuwien.kr.alpha.api.programs.Predicate)1 AggregateAtom (at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom)1 Atom (at.ac.tuwien.kr.alpha.api.programs.atoms.Atom)1 BasicAtom (at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom)1