Search in sources :

Example 6 with Literal

use of at.ac.tuwien.kr.alpha.api.programs.literals.Literal 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 7 with Literal

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

the class StratifiedEvaluation method apply.

@Override
public // memories created here rather than re-initialize everything.
InternalProgram apply(AnalyzedProgram inputProgram) {
    // Calculate a stratification and initialize the working memory.
    ComponentGraph componentGraph = inputProgram.getComponentGraph();
    List<ComponentGraph.SCComponent> strata = StratificationAlgorithm.calculateStratification(componentGraph);
    predicateDefiningRules = inputProgram.getPredicateDefiningRules();
    // Set up list of atoms which are known to be true - these will be expand by the evaluation.
    Map<Predicate, Set<Instance>> knownFacts = new LinkedHashMap<>(inputProgram.getFactsByPredicate());
    for (Map.Entry<Predicate, Set<Instance>> entry : knownFacts.entrySet()) {
        workingMemory.initialize(entry.getKey());
        workingMemory.addInstances(entry.getKey(), true, entry.getValue());
    }
    // Create working memories for all predicates occurring in each rule.
    for (CompiledRule nonGroundRule : inputProgram.getRulesById().values()) {
        for (Predicate predicate : nonGroundRule.getOccurringPredicates()) {
            workingMemory.initialize(predicate);
        }
    }
    workingMemory.reset();
    // Set up literal instantiator.
    literalInstantiator = new LiteralInstantiator(new WorkingMemoryBasedInstantiationStrategy(workingMemory));
    // Evaluate the program part covered by the calculated stratification.
    for (ComponentGraph.SCComponent currComponent : strata) {
        evaluateComponent(currComponent);
    }
    // Build the program resulting from evaluating the stratified part.
    // Add original input facts to newly derived ones.
    additionalFacts.addAll(inputProgram.getFacts());
    List<CompiledRule> outputRules = new ArrayList<>();
    inputProgram.getRulesById().entrySet().stream().filter((entry) -> !solvedRuleIds.contains(entry.getKey())).forEach((entry) -> outputRules.add(entry.getValue()));
    // NOTE: if InternalProgram requires solved rules, they should be added here.
    return new InternalProgram(outputRules, additionalFacts);
}
Also used : InternalProgram(at.ac.tuwien.kr.alpha.core.programs.InternalProgram) Substitution(at.ac.tuwien.kr.alpha.api.grounder.Substitution) BasicSubstitution(at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution) AnalyzedProgram(at.ac.tuwien.kr.alpha.core.programs.AnalyzedProgram) LoggerFactory(org.slf4j.LoggerFactory) HashMap(java.util.HashMap) Literal(at.ac.tuwien.kr.alpha.api.programs.literals.Literal) Stack(java.util.Stack) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) LiteralInstantiationResult(at.ac.tuwien.kr.alpha.core.grounder.instantiation.LiteralInstantiationResult) Map(java.util.Map) WorkingMemory(at.ac.tuwien.kr.alpha.core.grounder.WorkingMemory) SetUtils(org.apache.commons.collections4.SetUtils) LiteralInstantiator(at.ac.tuwien.kr.alpha.core.grounder.instantiation.LiteralInstantiator) CompiledRule(at.ac.tuwien.kr.alpha.core.rules.CompiledRule) LinkedHashSet(java.util.LinkedHashSet) AssignmentStatus(at.ac.tuwien.kr.alpha.core.grounder.instantiation.AssignmentStatus) Logger(org.slf4j.Logger) StratificationAlgorithm(at.ac.tuwien.kr.alpha.core.depgraph.StratificationAlgorithm) Atom(at.ac.tuwien.kr.alpha.api.programs.atoms.Atom) DependencyGraph(at.ac.tuwien.kr.alpha.api.programs.analysis.DependencyGraph) Set(java.util.Set) WorkingMemoryBasedInstantiationStrategy(at.ac.tuwien.kr.alpha.core.grounder.instantiation.WorkingMemoryBasedInstantiationStrategy) Atoms(at.ac.tuwien.kr.alpha.commons.atoms.Atoms) RuleGroundingOrder(at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingOrder) ImmutablePair(org.apache.commons.lang3.tuple.ImmutablePair) List(java.util.List) Instance(at.ac.tuwien.kr.alpha.commons.substitutions.Instance) IndexedInstanceStorage(at.ac.tuwien.kr.alpha.core.grounder.IndexedInstanceStorage) Collections(java.util.Collections) RuleGroundingInfo(at.ac.tuwien.kr.alpha.core.grounder.RuleGroundingInfo) Predicate(at.ac.tuwien.kr.alpha.api.programs.Predicate) ComponentGraph(at.ac.tuwien.kr.alpha.api.programs.analysis.ComponentGraph) WorkingMemoryBasedInstantiationStrategy(at.ac.tuwien.kr.alpha.core.grounder.instantiation.WorkingMemoryBasedInstantiationStrategy) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) LiteralInstantiator(at.ac.tuwien.kr.alpha.core.grounder.instantiation.LiteralInstantiator) ArrayList(java.util.ArrayList) InternalProgram(at.ac.tuwien.kr.alpha.core.programs.InternalProgram) Predicate(at.ac.tuwien.kr.alpha.api.programs.Predicate) LinkedHashMap(java.util.LinkedHashMap) ComponentGraph(at.ac.tuwien.kr.alpha.api.programs.analysis.ComponentGraph) CompiledRule(at.ac.tuwien.kr.alpha.core.rules.CompiledRule) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 8 with Literal

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

the class StratifiedEvaluation method calcSubstitutionsWithGroundingOrder.

private List<Substitution> calcSubstitutionsWithGroundingOrder(RuleGroundingOrder groundingOrder, List<Substitution> startingSubstitutions) {
    // Iterate through the grounding order and whenever instantiation of a Literal with a given substitution
    // causes a result with a type other than CONTINUE, discard that substitution.
    // Note that this function uses a stack of partial substitutions to simulate a recursive function.
    // For speed, we really want ArrayLists on the stack.
    Stack<ArrayList<Substitution>> substitutionStack = new Stack<>();
    if (startingSubstitutions instanceof ArrayList) {
        substitutionStack.push((ArrayList<Substitution>) startingSubstitutions);
    } else {
        // Copy startingSubstitutions into ArrayList. Note: mostly happens for empty or
        substitutionStack.push(new ArrayList<>(startingSubstitutions));
    // singleton lists.
    }
    int currentOrderPosition = 0;
    List<Substitution> fullSubstitutions = new ArrayList<>();
    while (!substitutionStack.isEmpty()) {
        List<Substitution> currentSubstitutions = substitutionStack.peek();
        // If no more substitutions remain at current position, all have been processed, continue on next lower level.
        if (currentSubstitutions.isEmpty()) {
            substitutionStack.pop();
            currentOrderPosition--;
            continue;
        }
        // In case the full grounding order has been worked on, all current substitutions are full substitutions, add them to
        // result.
        Literal currentLiteral = groundingOrder.getLiteralAtOrderPosition(currentOrderPosition);
        if (currentLiteral == null) {
            fullSubstitutions.addAll(currentSubstitutions);
            currentSubstitutions.clear();
            // Continue on next lower level.
            substitutionStack.pop();
            currentOrderPosition--;
            continue;
        }
        // Take one substitution from the top-list of the stack and try extending it.
        // Work on last element (removing last element is
        Substitution currentSubstitution = currentSubstitutions.remove(currentSubstitutions.size() - 1);
        // O(1) for ArrayList).
        LiteralInstantiationResult currentLiteralResult = literalInstantiator.instantiateLiteral(currentLiteral, currentSubstitution);
        if (currentLiteralResult.getType() == LiteralInstantiationResult.Type.CONTINUE) {
            // The currentSubstitution could be extended, push the extensions on the stack and continue working on them.
            ArrayList<Substitution> furtheredSubstitutions = new ArrayList<>();
            for (ImmutablePair<Substitution, AssignmentStatus> resultSubstitution : currentLiteralResult.getSubstitutions()) {
                furtheredSubstitutions.add(resultSubstitution.left);
            }
            substitutionStack.push(furtheredSubstitutions);
            // Continue work on the higher level.
            currentOrderPosition++;
        }
    }
    return fullSubstitutions;
}
Also used : Substitution(at.ac.tuwien.kr.alpha.api.grounder.Substitution) BasicSubstitution(at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution) LiteralInstantiationResult(at.ac.tuwien.kr.alpha.core.grounder.instantiation.LiteralInstantiationResult) Literal(at.ac.tuwien.kr.alpha.api.programs.literals.Literal) ArrayList(java.util.ArrayList) AssignmentStatus(at.ac.tuwien.kr.alpha.core.grounder.instantiation.AssignmentStatus) Stack(java.util.Stack)

Example 9 with Literal

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

the class StratifiedEvaluation method getRulesToEvaluate.

private ComponentEvaluationInfo getRulesToEvaluate(ComponentGraph.SCComponent comp) {
    Set<CompiledRule> nonRecursiveRules = new HashSet<>();
    Set<CompiledRule> recursiveRules = new HashSet<>();
    // Collect all predicates occurring in heads of rules of the given component.
    Set<Predicate> headPredicates = new HashSet<>();
    for (DependencyGraph.Node node : comp.getNodes()) {
        headPredicates.add(node.getPredicate());
    }
    // cycle.
    for (Predicate headPredicate : headPredicates) {
        HashSet<CompiledRule> definingRules = predicateDefiningRules.get(headPredicate);
        if (definingRules == null) {
            // Predicate only occurs in facts, skip.
            continue;
        }
        // Note: here we assume that all rules defining a predicate belong to the same SC component.
        for (CompiledRule rule : definingRules) {
            boolean isRuleRecursive = false;
            for (Literal lit : rule.getPositiveBody()) {
                if (headPredicates.contains(lit.getPredicate())) {
                    // The rule body contains a predicate that is defined in the same
                    // component, the rule is therefore part of a cyclic dependency within
                    // this component.
                    isRuleRecursive = true;
                }
            }
            if (isRuleRecursive) {
                recursiveRules.add(rule);
            } else {
                nonRecursiveRules.add(rule);
            }
        }
    }
    return new ComponentEvaluationInfo(nonRecursiveRules, recursiveRules);
}
Also used : CompiledRule(at.ac.tuwien.kr.alpha.core.rules.CompiledRule) Literal(at.ac.tuwien.kr.alpha.api.programs.literals.Literal) DependencyGraph(at.ac.tuwien.kr.alpha.api.programs.analysis.DependencyGraph) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) Predicate(at.ac.tuwien.kr.alpha.api.programs.Predicate)

Example 10 with Literal

use of at.ac.tuwien.kr.alpha.api.programs.literals.Literal 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)

Aggregations

Literal (at.ac.tuwien.kr.alpha.api.programs.literals.Literal)82 Test (org.junit.jupiter.api.Test)42 VariableTerm (at.ac.tuwien.kr.alpha.api.terms.VariableTerm)20 ArrayList (java.util.ArrayList)20 AggregateLiteral (at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral)17 Atom (at.ac.tuwien.kr.alpha.api.programs.atoms.Atom)16 Substitution (at.ac.tuwien.kr.alpha.api.grounder.Substitution)14 Predicate (at.ac.tuwien.kr.alpha.api.programs.Predicate)14 BasicAtom (at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom)14 BasicSubstitution (at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution)13 Map (java.util.Map)12 Head (at.ac.tuwien.kr.alpha.api.rules.heads.Head)11 CompiledProgram (at.ac.tuwien.kr.alpha.core.programs.CompiledProgram)11 CompiledRule (at.ac.tuwien.kr.alpha.core.rules.CompiledRule)10 HashSet (java.util.HashSet)10 ComparisonLiteral (at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral)9 Instance (at.ac.tuwien.kr.alpha.commons.substitutions.Instance)9 LinkedHashSet (java.util.LinkedHashSet)8 List (java.util.List)8 Term (at.ac.tuwien.kr.alpha.api.terms.Term)7