use of at.ac.tuwien.kr.alpha.api.grounder.Substitution 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.api.grounder.Substitution 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();
}
}
use of at.ac.tuwien.kr.alpha.api.grounder.Substitution in project Alpha by alpha-asp.
the class NaiveGrounder method getNoGoods.
@Override
public Map<Integer, NoGood> getNoGoods(Assignment currentAssignment) {
// In first call, prepare facts and ground rules.
final Map<Integer, NoGood> newNoGoods = fixedRules != null ? bootstrap() : new LinkedHashMap<>();
// Compute new ground rule (evaluate joins with newly changed atoms)
for (IndexedInstanceStorage modifiedWorkingMemory : workingMemory.modified()) {
// Skip predicates solely used in the solver which do not occur in rules.
Predicate workingMemoryPredicate = modifiedWorkingMemory.getPredicate();
if (workingMemoryPredicate.isSolverInternal()) {
continue;
}
// Iterate over all rules whose body contains the interpretation corresponding to the current workingMemory.
final ArrayList<FirstBindingAtom> firstBindingAtoms = rulesUsingPredicateWorkingMemory.get(modifiedWorkingMemory);
// Skip working memories that are not used by any rule.
if (firstBindingAtoms == null) {
continue;
}
for (FirstBindingAtom firstBindingAtom : firstBindingAtoms) {
// Use the recently added instances from the modified working memory to construct an initial substitution
CompiledRule nonGroundRule = firstBindingAtom.rule;
// Generate substitutions from each recent instance.
for (Instance instance : modifiedWorkingMemory.getRecentlyAddedInstances()) {
// Check instance if it matches with the atom.
final Substitution unifier = BasicSubstitution.specializeSubstitution(firstBindingAtom.startingLiteral, instance, BasicSubstitution.EMPTY_SUBSTITUTION);
if (unifier == null) {
continue;
}
final BindingResult bindingResult = getGroundInstantiations(nonGroundRule, nonGroundRule.getGroundingInfo().orderStartingFrom(firstBindingAtom.startingLiteral), unifier, currentAssignment);
groundAndRegister(nonGroundRule, bindingResult.getGeneratedSubstitutions(), newNoGoods);
}
}
// Mark instances added by updateAssignment as done
modifiedWorkingMemory.markRecentlyAddedInstancesDone();
}
workingMemory.reset();
for (Atom removeAtom : removeAfterObtainingNewNoGoods) {
final IndexedInstanceStorage storage = workingMemory.get(removeAtom, true);
Instance instance = new Instance(removeAtom.getTerms());
if (storage.containsInstance(instance)) {
// permissive grounder heuristics may attempt to remove instances that are not yet in the working memory
storage.removeInstance(instance);
}
}
// Re-Initialize the stale working memory entries set and pass to instantiation strategy.
removeAfterObtainingNewNoGoods = new LinkedHashSet<>();
instantiationStrategy.setStaleWorkingMemoryEntries(removeAfterObtainingNewNoGoods);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Grounded NoGoods are:");
for (Map.Entry<Integer, NoGood> noGoodEntry : newNoGoods.entrySet()) {
LOGGER.debug("{} == {}", noGoodEntry.getValue(), atomStore.noGoodToString(noGoodEntry.getValue()));
}
LOGGER.debug("{}", choiceRecorder);
}
if (debugInternalChecks) {
checkTypesOfNoGoods(newNoGoods.values());
}
return newNoGoods;
}
use of at.ac.tuwien.kr.alpha.api.grounder.Substitution 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);
}
}
use of at.ac.tuwien.kr.alpha.api.grounder.Substitution in project Alpha by alpha-asp.
the class LiteralInstantiationStrategyTest method defaultLazyGroundingSubstituteNonGroundLiteralWithTrueInstance.
/**
* Uses {@link DefaultLazyGroundingInstantiationStrategy} to find the ground
* instance "q(a, b)" for the partially ground positive literal "q(a, X)".
*
* In this case, the instantiation strategy has an assignment where q(a, b) is
* assigned ThriceTruth.TRUE, so we expect the assignment status (i.e.
* assignment status of the found ground instance) passed back with the
* substitution to be TRUE. Furthermore, we expect the stale atom set to stay
* empty.
*/
@Test
public void defaultLazyGroundingSubstituteNonGroundLiteralWithTrueInstance() {
Predicate q = Predicates.getPredicate("q", 2);
BasicAtom nonGroundAtom = Atoms.newBasicAtom(q, Terms.newSymbolicConstant("a"), Terms.newVariable("X"));
WorkingMemory workingMemory = new WorkingMemory();
workingMemory.initialize(q);
workingMemory.addInstance(Atoms.newBasicAtom(q, Terms.newSymbolicConstant("a"), Terms.newSymbolicConstant("b")), true);
AtomStore atomStore = new AtomStoreImpl();
WritableAssignment assignment = new TrailAssignment(atomStore);
BasicAtom groundAtom = Atoms.newBasicAtom(q, Terms.newSymbolicConstant("a"), Terms.newSymbolicConstant("b"));
atomStore.putIfAbsent(groundAtom);
assignment.growForMaxAtomId();
assignment.assign(atomStore.get(groundAtom), ThriceTruth.TRUE);
LinkedHashSet<Atom> staleSet = new LinkedHashSet<>();
DefaultLazyGroundingInstantiationStrategy strategy = new DefaultLazyGroundingInstantiationStrategy(workingMemory, atomStore, Collections.emptyMap(), false);
strategy.setStaleWorkingMemoryEntries(staleSet);
strategy.setCurrentAssignment(assignment);
List<ImmutablePair<Substitution, AssignmentStatus>> result = strategy.getAcceptedSubstitutions(Literals.fromAtom(nonGroundAtom, true), new BasicSubstitution());
assertEquals(1, result.size());
ImmutablePair<Substitution, AssignmentStatus> substitutionInfo = result.get(0);
Substitution substitution = substitutionInfo.left;
AssignmentStatus assignmentStatus = substitutionInfo.right;
assertEquals(AssignmentStatus.TRUE, assignmentStatus);
assertTrue(substitution.isVariableSet(Terms.newVariable("X")));
assertEquals(Terms.newSymbolicConstant("b"), substitution.eval(Terms.newVariable("X")));
assertTrue(staleSet.isEmpty());
}
Aggregations