use of at.ac.tuwien.kr.alpha.api.programs.literals.Literal in project Alpha by alpha-asp.
the class AggregateRewritingRuleAnalysisTest method nonBindingAggregateNoGlobals1.
@Test
public void nonBindingAggregateNoGlobals1() {
AggregateRewritingRuleAnalysis analysis = analyze(NONBINDING_AGGREGATE_NO_GLOBALS_1);
assertEquals(1, analysis.globalVariablesPerAggregate.size());
assertEquals(1, analysis.dependenciesPerAggregate.size());
AggregateLiteral aggregate = new ArrayList<>(analysis.globalVariablesPerAggregate.keySet()).get(0);
assertTrue(analysis.globalVariablesPerAggregate.get(aggregate).isEmpty());
assertFalse(analysis.dependenciesPerAggregate.get(aggregate).isEmpty());
Set<Literal> dependencies = analysis.dependenciesPerAggregate.get(aggregate);
assertEquals(1, dependencies.size());
Literal pXY = Literals.fromAtom(Atoms.newBasicAtom(Predicates.getPredicate("p", 2), Terms.newVariable("X"), Terms.newVariable("Y")), true);
assertTrue(dependencies.contains(pXY));
}
use of at.ac.tuwien.kr.alpha.api.programs.literals.Literal in project Alpha by alpha-asp.
the class SubstitutionTestUtil method groundAndPrintRule.
public static String groundAndPrintRule(CompiledRule rule, Substitution substitution) {
StringBuilder ret = new StringBuilder();
if (!rule.isConstraint()) {
Atom groundHead = rule.getHeadAtom().substitute(substitution);
ret.append(groundHead.toString());
}
ret.append(" :- ");
boolean isFirst = true;
for (Literal lit : rule.getBody()) {
ret.append(groundLiteralToString(lit, substitution, isFirst));
isFirst = false;
}
ret.append(".");
return ret.toString();
}
use of at.ac.tuwien.kr.alpha.api.programs.literals.Literal 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.api.programs.literals.Literal 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.api.programs.literals.Literal in project Alpha by alpha-asp.
the class RuleGroundingInfoImpl method computeGroundingOrder.
private void computeGroundingOrder(Literal startingLiteral) {
Set<Literal> bodyLiterals = internalRule.getBody();
HashSet<VariableTerm> boundVariables = new HashSet<>();
boundVariables.addAll(startingLiteral.getBindingVariables());
LinkedHashSet<Literal> remainingLiterals = new LinkedHashSet<>(bodyLiterals);
remainingLiterals.remove(startingLiteral);
ArrayList<Literal> literalsOrder;
if (fixedGroundingInstantiation) {
literalsOrder = new ArrayList<>(bodyLiterals.size());
literalsOrder.add(startingLiteral);
} else {
literalsOrder = new ArrayList<>(bodyLiterals.size() - 1);
}
int position = 0;
int positionLastVarBound = -1;
while (!remainingLiterals.isEmpty()) {
Literal nextGroundingLiteral = selectNextGroundingLiteral(remainingLiterals, boundVariables);
if (nextGroundingLiteral == null) {
throw new RuntimeException("Could not find a grounding order for rule " + internalRule + " with starting literal: " + startingLiteral + ". Rule is not safe.");
}
remainingLiterals.remove(nextGroundingLiteral);
boolean boundNewVars = boundVariables.addAll(nextGroundingLiteral.getBindingVariables());
if (boundNewVars) {
positionLastVarBound = position;
}
literalsOrder.add(nextGroundingLiteral);
position++;
}
if (fixedGroundingInstantiation) {
fixedGroundingOrder = new RuleGroundingOrderImpl(null, literalsOrder, positionLastVarBound, internalRule.isGround());
}
groundingOrders.put(startingLiteral, new RuleGroundingOrderImpl(startingLiteral, literalsOrder, positionLastVarBound, internalRule.isGround()));
}
Aggregations