use of at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution in project Alpha by alpha-asp.
the class ComparisonLiteralImpl method getSatisfyingSubstitutions.
@Override
public List<Substitution> getSatisfyingSubstitutions(Substitution partialSubstitution) {
// Treat case where this is just comparison with all variables bound by partialSubstitution.
final Term left = getAtom().getTerms().get(0).substitute(partialSubstitution);
final Term right = getAtom().getTerms().get(1).substitute(partialSubstitution);
final boolean leftAssigning = assignable(left);
final boolean rightAssigning = assignable(right);
if (!leftAssigning && !rightAssigning) {
// No assignment (variables are bound by partialSubstitution), thus evaluate comparison only.
Term leftEvaluatedSubstitute = evaluateTerm(left);
if (leftEvaluatedSubstitute == null) {
return Collections.emptyList();
}
Term rightEvaluatedSubstitute = evaluateTerm(right);
if (rightEvaluatedSubstitute == null) {
return Collections.emptyList();
}
if (compare(leftEvaluatedSubstitute, rightEvaluatedSubstitute)) {
return Collections.singletonList(partialSubstitution);
} else {
return Collections.emptyList();
}
}
// Treat case that this is X = t or t = X.
VariableTerm variable = null;
Term expression = null;
if (leftAssigning) {
variable = (VariableTerm) left;
expression = right;
}
if (rightAssigning) {
variable = (VariableTerm) right;
expression = left;
}
Term groundTerm = expression.substitute(partialSubstitution);
Term resultTerm = null;
// Check if the groundTerm is an arithmetic expression and evaluate it if so.
if (groundTerm instanceof ArithmeticTerm) {
Integer result = Terms.evaluateGroundTerm(groundTerm);
if (result == null) {
return Collections.emptyList();
}
resultTerm = Terms.newConstant(result);
} else {
// Ground term is another term (constant, or function term).
resultTerm = groundTerm;
}
BasicSubstitution extendedSubstitution = new BasicSubstitution(partialSubstitution);
extendedSubstitution.put(variable, resultTerm);
return Collections.singletonList(extendedSubstitution);
}
use of at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution in project Alpha by alpha-asp.
the class NaiveGrounder method bootstrap.
/**
* Prepares facts of the input program for joining and derives all NoGoods representing ground rules. May only be called once.
*
* @return
*/
protected HashMap<Integer, NoGood> bootstrap() {
final HashMap<Integer, NoGood> groundNogoods = new LinkedHashMap<>();
for (Predicate predicate : factsFromProgram.keySet()) {
// Instead of generating NoGoods, add instance to working memories directly.
workingMemory.addInstances(predicate, true, factsFromProgram.get(predicate));
}
for (CompiledRule nonGroundRule : fixedRules) {
// Generate NoGoods for all rules that have a fixed grounding.
RuleGroundingOrder groundingOrder = nonGroundRule.getGroundingInfo().getFixedGroundingOrder();
BindingResult bindingResult = getGroundInstantiations(nonGroundRule, groundingOrder, new BasicSubstitution(), null);
groundAndRegister(nonGroundRule, bindingResult.getGeneratedSubstitutions(), groundNogoods);
}
fixedRules = null;
return groundNogoods;
}
use of at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution 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.commons.substitutions.BasicSubstitution in project Alpha by alpha-asp.
the class ExternalLiteralImpl method buildSubstitutionsForOutputs.
private List<Substitution> buildSubstitutionsForOutputs(Substitution partialSubstitution, Set<List<ConstantTerm<?>>> outputs) {
List<Substitution> retVal = new ArrayList<>();
List<Term> externalAtomOutputTerms = this.getAtom().getOutput();
for (List<ConstantTerm<?>> bindings : outputs) {
if (bindings.size() < externalAtomOutputTerms.size()) {
throw new RuntimeException("Predicate " + getPredicate().getName() + " returned " + bindings.size() + " terms when at least " + externalAtomOutputTerms.size() + " were expected.");
}
BasicSubstitution ith = new BasicSubstitution(partialSubstitution);
boolean skip = false;
for (int i = 0; i < externalAtomOutputTerms.size(); i++) {
Term out = externalAtomOutputTerms.get(i);
if (out instanceof VariableTerm) {
ith.put((VariableTerm) out, bindings.get(i));
} else {
if (!bindings.get(i).equals(out)) {
skip = true;
break;
}
}
}
if (!skip) {
retVal.add(ith);
}
}
return retVal;
}
use of at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution in project Alpha by alpha-asp.
the class IntervalLiteral method getIntervalSubstitutions.
private List<Substitution> getIntervalSubstitutions(Substitution partialSubstitution) {
List<Substitution> substitutions = new ArrayList<>();
List<Term> terms = getTerms();
Term intervalRepresentingVariable = terms.get(1);
IntervalTerm intervalTerm = (IntervalTerm) terms.get(0);
// Check whether intervalRepresentingVariable is bound already.
if (intervalRepresentingVariable instanceof VariableTerm) {
// Still a variable, generate all elements in the interval.
for (int i = intervalTerm.getLowerBound(); i <= intervalTerm.getUpperBound(); i++) {
Substitution ith = new BasicSubstitution(partialSubstitution);
ith.put((VariableTerm) intervalRepresentingVariable, Terms.newConstant(i));
substitutions.add(ith);
}
return substitutions;
} else {
// The intervalRepresentingVariable is bound already, check if it is in the interval.
if (!(intervalRepresentingVariable instanceof ConstantTerm) || !(((ConstantTerm<?>) intervalRepresentingVariable).getObject() instanceof Integer)) {
// Term is not bound to an integer constant, not in the interval.
return Collections.emptyList();
}
// TODO to avoid that type of unchecked cast, we may want interval terms to not extend AbstractTerm
@SuppressWarnings("unchecked") Integer integer = ((ConstantTerm<Integer>) intervalRepresentingVariable).getObject();
if (intervalTerm.getLowerBound() <= integer && integer <= intervalTerm.getUpperBound()) {
return Collections.singletonList(partialSubstitution);
}
return Collections.emptyList();
}
}
Aggregations