use of at.ac.tuwien.kr.alpha.core.grounder.instantiation.AssignmentStatus in project Alpha by alpha-asp.
the class NaiveGrounder method bindNextAtomInRule.
// @formatter:off
/**
* Computes ground substitutions for a literal based on a {@link RuleGroundingOrderImpl} and a {@link BasicSubstitution}.
*
* Computes ground substitutions for the literal at position <code>orderPosition</code> of <code>groundingOrder</code>
* Actual substitutions are computed by this grounder's {@link LiteralInstantiator}.
*
* @param groundingOrder a {@link RuleGroundingOrderImpl} representing the body literals of a rule in the
* sequence in which the should be bound during grounding.
* @param orderPosition the current position within <code>groundingOrder</code>, indicates which literal should be bound
* @param originalTolerance the original tolerance of the used grounding heuristic
* @param remainingTolerance the remaining tolerance, determining if binding continues in the presence of substitutions based on unassigned atoms
* @param partialSubstitution a substitution
* @return a {@link BindingResult} representing applicable ground substitutions for all literals after orderPosition in groundingOrder
*/
// @formatter:on
private BindingResult bindNextAtomInRule(RuleGroundingOrder groundingOrder, int orderPosition, int originalTolerance, int remainingTolerance, Substitution partialSubstitution) {
Literal currentLiteral = groundingOrder.getLiteralAtOrderPosition(orderPosition);
if (currentLiteral == null) {
LOGGER.trace("No more literals found in grounding order, therefore stopping binding!");
return BindingResult.singleton(partialSubstitution, originalTolerance - remainingTolerance);
}
LOGGER.trace("Binding current literal {} with remaining tolerance {} and partial substitution {}.", currentLiteral, remainingTolerance, partialSubstitution);
LiteralInstantiationResult instantiationResult = ruleInstantiator.instantiateLiteral(currentLiteral, partialSubstitution);
switch(instantiationResult.getType()) {
case CONTINUE:
/*
* Recursively call bindNextAtomInRule for each generated substitution
* and the next literal in the grounding order (i.e. advance), thereby reducing remaining
* tolerance by 1 iff a substitution uses an unassigned ground atom.
* If remainingTolerance falls below zero, an empty {@link BindingResult} is returned.
*/
List<ImmutablePair<Substitution, AssignmentStatus>> substitutionInfos = instantiationResult.getSubstitutions();
LOGGER.trace("Literal instantiator yielded {} substitutions for literal {}.", substitutionInfos.size(), currentLiteral);
BindingResult retVal = new BindingResult();
for (ImmutablePair<Substitution, AssignmentStatus> substitutionInfo : substitutionInfos) {
retVal.add(this.continueBinding(groundingOrder, orderPosition, originalTolerance, remainingTolerance, substitutionInfo));
}
return retVal;
case PUSH_BACK:
/*
* Delegate to pushBackAndBindNextAtomInRule(RuleGroundingOrder, int, int, int, Substitution, Assignment).
* Pushes the current literal to the end of the grounding order and calls bindNextAtomInRule with the modified grounding oder.
*/
LOGGER.trace("Pushing back literal {} in grounding order.", currentLiteral);
return pushBackAndBindNextAtomInRule(groundingOrder, orderPosition, originalTolerance, remainingTolerance, partialSubstitution);
case MAYBE_PUSH_BACK:
/*
* Indicates that the rule instantiator could not find any substitutions for the current literal. If a permissive grounder heuristic is in
* use, push the current literal to the end of the grounding order and proceed with the next one, otherwise return an empty BindingResult.
*/
if (originalTolerance > 0) {
LOGGER.trace("No substitutions yielded by literal instantiator for literal {}, but using permissive heuristic, therefore pushing the literal back.", currentLiteral);
// i.e. it is deemed acceptable to have ground rules where a number of body atoms are not yet assigned a truth value by the solver.
return pushBackAndBindNextAtomInRule(groundingOrder, orderPosition, originalTolerance, remainingTolerance, partialSubstitution);
} else {
LOGGER.trace("No substitutions found for literal {}", currentLiteral);
return BindingResult.empty();
}
case STOP_BINDING:
LOGGER.trace("No substitutions found for literal {}", currentLiteral);
return BindingResult.empty();
default:
throw Util.oops("Unhandled literal instantiation result type: " + instantiationResult.getType());
}
}
use of at.ac.tuwien.kr.alpha.core.grounder.instantiation.AssignmentStatus 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.core.grounder.instantiation.AssignmentStatus in project Alpha by alpha-asp.
the class NaiveGrounder method continueBinding.
/**
* Helper method used by {@link NaiveGrounder#bindNextAtomInRule(RuleGroundingOrderImpl, int, int, int, BasicSubstitution)}.
*
* Takes an <code>ImmutablePair</code> of a {@link BasicSubstitution} and an accompanying {@link AssignmentStatus} and calls
* <code>bindNextAtomInRule</code> for the next literal in the grounding order.
* If the assignment status for the last bound literal was {@link AssignmentStatus#UNASSIGNED}, the <code>remainingTolerance</code>
* parameter is decreased by 1. If the remaining tolerance drops below zero, this method returns an empty {@link BindingResult}.
*
* @param groundingOrder
* @param orderPosition
* @param originalTolerance
* @param remainingTolerance
* @param lastLiteralBindingResult
* @return the result of calling bindNextAtomInRule on the next literal in the grounding order, or an empty binding result if remaining
* tolerance is less than zero.
*/
private BindingResult continueBinding(RuleGroundingOrder groundingOrder, int orderPosition, int originalTolerance, int remainingTolerance, ImmutablePair<Substitution, AssignmentStatus> lastLiteralBindingResult) {
Substitution substitution = lastLiteralBindingResult.left;
AssignmentStatus lastBoundLiteralAssignmentStatus = lastLiteralBindingResult.right;
switch(lastBoundLiteralAssignmentStatus) {
case TRUE:
return advanceAndBindNextAtomInRule(groundingOrder, orderPosition, originalTolerance, remainingTolerance, substitution);
case UNASSIGNED:
// The last literal bound to obtain the current substitution has not been assigned a truth value by the solver yet.
// If we still have enough tolerance, we can continue grounding nevertheless.
int toleranceForNextRun = remainingTolerance - 1;
if (toleranceForNextRun >= 0) {
return advanceAndBindNextAtomInRule(groundingOrder, orderPosition, originalTolerance, toleranceForNextRun, substitution);
} else {
return BindingResult.empty();
}
case FALSE:
throw Util.oops("Got an assignmentStatus FALSE for literal " + groundingOrder.getLiteralAtOrderPosition(orderPosition) + " and substitution " + substitution + " - should not happen!");
default:
throw Util.oops("Got unsupported assignmentStatus " + lastBoundLiteralAssignmentStatus);
}
}
Aggregations