use of at.ac.tuwien.kr.alpha.core.rules.CompiledRule 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.core.rules.CompiledRule in project Alpha by alpha-asp.
the class NaiveGrounder method getRulesWithUniqueHead.
private Set<CompiledRule> getRulesWithUniqueHead() {
// FIXME: below optimisation (adding support nogoods if there is only one rule instantiation per unique atom over the interpretation) could
// be done as a transformation (adding a non-ground constraint corresponding to the nogood that is generated by the grounder).
// Record all unique rule heads.
final Set<CompiledRule> uniqueGroundRulePerGroundHead = new HashSet<>();
for (Map.Entry<Predicate, LinkedHashSet<CompiledRule>> headDefiningRules : program.getPredicateDefiningRules().entrySet()) {
if (headDefiningRules.getValue().size() != 1) {
continue;
}
CompiledRule nonGroundRule = headDefiningRules.getValue().iterator().next();
// Check that all variables of the body also occur in the head (otherwise grounding is not unique).
Atom headAtom = nonGroundRule.getHeadAtom();
// Rule is not guaranteed unique if there are facts for it.
HashSet<Instance> potentialFacts = factsFromProgram.get(headAtom.getPredicate());
if (potentialFacts != null && !potentialFacts.isEmpty()) {
continue;
}
// Collect head and body variables.
HashSet<VariableTerm> occurringVariablesHead = new HashSet<>(headAtom.toLiteral().getBindingVariables());
HashSet<VariableTerm> occurringVariablesBody = new HashSet<>();
for (Literal lit : nonGroundRule.getPositiveBody()) {
occurringVariablesBody.addAll(lit.getBindingVariables());
}
occurringVariablesBody.removeAll(occurringVariablesHead);
// Check if ever body variables occurs in the head.
if (occurringVariablesBody.isEmpty()) {
uniqueGroundRulePerGroundHead.add(nonGroundRule);
}
}
return uniqueGroundRulePerGroundHead;
}
use of at.ac.tuwien.kr.alpha.core.rules.CompiledRule 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.core.rules.CompiledRule in project Alpha by alpha-asp.
the class AtomCounterTests method createRuleAtom.
private void createRuleAtom() {
BasicAtom atomAA = Atoms.newBasicAtom(Predicates.getPredicate("aa", 0));
CompiledRule ruleAA = new InternalRule(Heads.newNormalHead(atomAA), Collections.singletonList(Atoms.newBasicAtom(Predicates.getPredicate("bb", 0)).toLiteral(false)));
atomStore.putIfAbsent(new RuleAtom(ruleAA, new BasicSubstitution()));
}
use of at.ac.tuwien.kr.alpha.core.rules.CompiledRule in project Alpha by alpha-asp.
the class StratifiedEvaluation method prepareInitialEvaluation.
/**
* To be called at the start of evaluateComponent. Adds all known instances of the predicates occurring in the given set
* of rules to the "modifiedInLastEvaluationRun" map in order to "bootstrap" incremental grounding, i.e. making sure
* that those instances are taken into account for ground substitutions by evaluateRule.
*/
private void prepareInitialEvaluation(Set<CompiledRule> rulesToEvaluate) {
modifiedInLastEvaluationRun = new HashMap<>();
for (CompiledRule rule : rulesToEvaluate) {
// Register rule head instances.
Predicate headPredicate = rule.getHeadAtom().getPredicate();
IndexedInstanceStorage headInstances = workingMemory.get(headPredicate, true);
modifiedInLastEvaluationRun.putIfAbsent(headPredicate, new LinkedHashSet<>());
if (headInstances != null) {
modifiedInLastEvaluationRun.get(headPredicate).addAll(headInstances.getAllInstances());
}
// Register positive body literal instances.
for (Literal lit : rule.getPositiveBody()) {
Predicate bodyPredicate = lit.getPredicate();
IndexedInstanceStorage bodyInstances = workingMemory.get(bodyPredicate, true);
modifiedInLastEvaluationRun.putIfAbsent(bodyPredicate, new LinkedHashSet<>());
if (bodyInstances != null) {
modifiedInLastEvaluationRun.get(bodyPredicate).addAll(bodyInstances.getAllInstances());
}
}
}
}
Aggregations