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;
}
}
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);
}
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;
}
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);
}
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;
}
Aggregations