use of at.ac.tuwien.kr.alpha.core.rules.CompiledRule 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.core.rules.CompiledRule 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.core.rules.CompiledRule in project Alpha by alpha-asp.
the class NaiveGrounderTest method testPermissiveGrounderHeuristicTolerance.
/**
* Tests if {@link NaiveGrounder#getGroundInstantiations(InternalRule, RuleGroundingOrder, Substitution, Assignment)}
* produces ground instantiations for the rule with ID {@code ruleID} in {@code program} when {@code startingLiteral}
* unified with the numeric instance {@code startingInstance} is used as starting literal and the following
* additional conditions are established:
* <ul>
* <li>The atoms {@code b([startingInstance], 1), ..., b([startingInstance], n)} are added to the grounder's
* working memory without changing the assignment, where {@code arityOfB-1} occurences of {@code startingInstance}
* are used instead of {@code [startingInstance]} and {@code n} is the length of the {@code truthsOfB} array.
* For example, if the length of {@code truthsOfB} is 2 and {@code arityOfB} is also 2, these atoms are
* {@code b(1,1), b(1,2)}.
* </li>
* <li>The same atoms are assigned the truth values in the {@code truthsOfB} array.</li>
* </ul>
* It is asserted that ground instantiations are produced if and only if {@code expectNoGoods} is true.
* If ground instantiations are produced, it is also asserted that the numbers of unassigned positive body atoms
* determined by {@code getGroundInstantiations} match those given in {@code expectedNumbersOfUnassignedPositiveBodyAtoms}.
*/
private void testPermissiveGrounderHeuristicTolerance(ASPCore2Program program, int ruleID, Literal startingLiteral, int startingInstance, int tolerance, ThriceTruth[] truthsOfB, int arityOfB, boolean expectNoGoods, List<Integer> expectedNumbersOfUnassignedPositiveBodyAtoms) {
CompiledProgram internalPrg = InternalProgram.fromNormalProgram(NORMALIZE_TRANSFORM.apply(program));
AtomStore atomStore = new AtomStoreImpl();
TrailAssignment currentAssignment = new TrailAssignment(atomStore);
GrounderHeuristicsConfiguration heuristicConfiguration = GrounderHeuristicsConfiguration.getInstance(tolerance, tolerance);
NaiveGrounder grounder = (NaiveGrounder) GrounderFactory.getInstance("naive", internalPrg, atomStore, p -> true, heuristicConfiguration, true);
int[] bAtomIDs = new int[truthsOfB.length];
for (int i = 0; i < truthsOfB.length; i++) {
int[] bTerms = new int[arityOfB];
for (int n = 0; n < arityOfB; n++) {
bTerms[n] = (n == arityOfB - 1) ? i + 1 : startingInstance;
}
bAtomIDs[i] = atomStore.putIfAbsent(atom("b", bTerms));
}
addAtomsToWorkingMemoryWithoutChangingTheAssignment(atomStore, grounder, bAtomIDs);
assign(currentAssignment, bAtomIDs, truthsOfB);
grounder.bootstrap();
final CompiledRule nonGroundRule = grounder.getNonGroundRule(ruleID);
final Substitution substStartingLiteral = BasicSubstitution.specializeSubstitution(startingLiteral, new Instance(Terms.newConstant(startingInstance)), BasicSubstitution.EMPTY_SUBSTITUTION);
final BindingResult bindingResult = grounder.getGroundInstantiations(nonGroundRule, nonGroundRule.getGroundingInfo().orderStartingFrom(startingLiteral), substStartingLiteral, currentAssignment);
assertEquals(expectNoGoods, bindingResult.size() > 0);
if (bindingResult.size() > 0) {
assertEquals(expectedNumbersOfUnassignedPositiveBodyAtoms, bindingResult.getNumbersOfUnassignedPositiveBodyAtoms());
} else {
assertTrue(bindingResult.getNumbersOfUnassignedPositiveBodyAtoms().isEmpty());
}
}
use of at.ac.tuwien.kr.alpha.core.rules.CompiledRule in project Alpha by alpha-asp.
the class RuleGroundingOrderTest method computeGroundingOrdersForRule.
private RuleGroundingInfo computeGroundingOrdersForRule(CompiledProgram program, int ruleIndex) {
CompiledRule rule = program.getRules().get(ruleIndex);
RuleGroundingInfo rgo = new RuleGroundingInfoImpl(rule);
rgo.computeGroundingOrders();
return rgo;
}
use of at.ac.tuwien.kr.alpha.core.rules.CompiledRule in project Alpha by alpha-asp.
the class RuleGroundingOrderTest method groundingOrder.
@Test
public void groundingOrder() {
String aspStr = "h(X,C) :- p(X,Y), q(A,B), r(Y,A), s(C)." + "j(A,B,X,Y) :- r1(A,B), r1(X,Y), r1(A,X), r1(B,Y), A = B." + "p(a) :- b = a.";
CompiledProgram prog = PARSE_AND_PREPROCESS.apply(aspStr);
CompiledRule rule0 = prog.getRules().get(0);
RuleGroundingInfo rgo0 = new RuleGroundingInfoImpl(rule0);
rgo0.computeGroundingOrders();
assertEquals(4, rgo0.getStartingLiterals().size());
CompiledRule rule1 = prog.getRules().get(1);
RuleGroundingInfo rgo1 = new RuleGroundingInfoImpl(rule1);
rgo1.computeGroundingOrders();
assertEquals(4, rgo1.getStartingLiterals().size());
CompiledRule rule2 = prog.getRules().get(2);
RuleGroundingInfo rgo2 = new RuleGroundingInfoImpl(rule2);
rgo2.computeGroundingOrders();
assertTrue(rgo2.hasFixedInstantiation());
}
Aggregations