use of at.ac.tuwien.kr.alpha.core.atoms.RuleAtom in project Alpha by alpha-asp.
the class SubstitutionTest method substitutionFromString.
@Test
public void substitutionFromString() {
Rule<Head> rule = PARSER.parse("x :- p(X,Y), not q(X,Y).").getRules().get(0);
CompiledRule nonGroundRule = InternalRule.fromNormalRule(NormalRuleImpl.fromBasicRule(rule));
Substitution substitution1 = BasicSubstitution.specializeSubstitution(PX, PA, BasicSubstitution.EMPTY_SUBSTITUTION);
Substitution substitution = BasicSubstitution.specializeSubstitution(PY, PB, substitution1);
RuleAtom ruleAtom = new RuleAtom(nonGroundRule, substitution);
String substitutionString = (String) ((ConstantTerm<?>) ruleAtom.getTerms().get(1)).getObject();
Substitution fromString = Substitutions.fromString(substitutionString);
assertEquals(substitution, fromString);
}
use of at.ac.tuwien.kr.alpha.core.atoms.RuleAtom in project Alpha by alpha-asp.
the class DefaultSolver method treatConflictAfterClosing.
private boolean treatConflictAfterClosing(Antecedent violatedNoGood) {
if (disableJustificationAfterClosing || disableJustifications || !(grounder instanceof ProgramAnalyzingGrounder)) {
// Will not learn from violated NoGood, do simple backtrack.
LOGGER.debug("NoGood was violated after all unassigned atoms were assigned to false; will not learn from it; skipping.");
if (!backtrack()) {
logStats();
return false;
}
return true;
}
ProgramAnalyzingGrounder analyzingGrounder = (ProgramAnalyzingGrounder) grounder;
LOGGER.debug("Justifying atoms in violated nogood.");
LinkedHashSet<Integer> toJustify = new LinkedHashSet<>();
// Find those literals in violatedNoGood that were just assigned false.
for (Integer literal : violatedNoGood.getReasonLiterals()) {
if (assignment.getImpliedBy(atomOf(literal)) == TrailAssignment.CLOSING_INDICATOR_ANTECEDENT) {
toJustify.add(literal);
}
}
// Since the violatedNoGood may contain atoms other than BasicAtom, these have to be treated.
Map<Integer, NoGood> obtained = new LinkedHashMap<>();
Iterator<Integer> toJustifyIterator = toJustify.iterator();
ArrayList<Integer> ruleAtomReplacements = new ArrayList<>();
while (toJustifyIterator.hasNext()) {
Integer literal = toJustifyIterator.next();
Atom atom = atomStore.get(atomOf(literal));
if (atom instanceof BasicAtom) {
continue;
}
if (!(atom instanceof RuleAtom)) {
// Ignore atoms other than RuleAtom.
toJustifyIterator.remove();
continue;
}
// For RuleAtoms in toJustify the corresponding ground body contains BasicAtoms that have been assigned FALSE in the closing.
// First, translate RuleAtom back to NonGroundRule + Substitution.
String ruleId = (String) ((ConstantTerm<?>) atom.getTerms().get(0)).getObject();
CompiledRule nonGroundRule = analyzingGrounder.getNonGroundRule(Integer.parseInt(ruleId));
String substitution = (String) ((ConstantTerm<?>) atom.getTerms().get(1)).getObject();
Substitution groundingSubstitution = Substitutions.fromString(substitution);
// Find ground literals in the body that have been assigned false and justify those.
for (Literal bodyLiteral : nonGroundRule.getBody()) {
Atom groundAtom = bodyLiteral.getAtom().substitute(groundingSubstitution);
if (groundAtom instanceof ComparisonAtom || analyzingGrounder.isFact(groundAtom)) {
// Facts and ComparisonAtoms are always true, no justification needed.
continue;
}
int groundAtomId = atomStore.get(groundAtom);
Antecedent impliedBy = assignment.getImpliedBy(groundAtomId);
// Check if atom was assigned to FALSE during the closing.
if (impliedBy == TrailAssignment.CLOSING_INDICATOR_ANTECEDENT) {
ruleAtomReplacements.add(atomToNegatedLiteral(groundAtomId));
}
}
toJustifyIterator.remove();
}
toJustify.addAll(ruleAtomReplacements);
for (Integer literalToJustify : toJustify) {
LOGGER.debug("Searching for justification(s) of {} / {}", toJustify, atomStore.atomToString(atomOf(literalToJustify)));
Set<Literal> reasonsForUnjustified = analyzingGrounder.justifyAtom(atomOf(literalToJustify), assignment);
NoGood noGood = noGoodFromJustificationReasons(atomOf(literalToJustify), reasonsForUnjustified);
int noGoodID = grounder.register(noGood);
obtained.put(noGoodID, noGood);
LOGGER.debug("Learned NoGood is: {}", atomStore.noGoodToString(noGood));
}
// Backtrack to remove the violation.
if (!backtrack()) {
logStats();
return false;
}
// Add newly obtained noGoods.
if (!ingest(obtained)) {
logStats();
return false;
}
return true;
}
use of at.ac.tuwien.kr.alpha.core.atoms.RuleAtom in project Alpha by alpha-asp.
the class NoGoodGenerator method generateNoGoodsFromGroundSubstitution.
/**
* Generates all NoGoods resulting from a non-ground rule and a variable substitution.
*
* @param nonGroundRule
* the non-ground rule.
* @param substitution
* the grounding substitution, i.e., applying substitution to nonGroundRule results in a ground rule.
* Assumption: atoms with fixed interpretation evaluate to true under the substitution.
* @return a list of the NoGoods corresponding to the ground rule.
*/
List<NoGood> generateNoGoodsFromGroundSubstitution(final CompiledRule nonGroundRule, final Substitution substitution) {
final List<Integer> posLiterals = collectPosLiterals(nonGroundRule, substitution);
final List<Integer> negLiterals = collectNegLiterals(nonGroundRule, substitution);
if (posLiterals == null || negLiterals == null) {
return emptyList();
}
// A constraint is represented by exactly one nogood.
if (nonGroundRule.isConstraint()) {
return singletonList(NoGood.fromConstraint(posLiterals, negLiterals));
}
final List<NoGood> result = new ArrayList<>();
final Atom groundHeadAtom = nonGroundRule.getHeadAtom().substitute(substitution);
final int headId = atomStore.putIfAbsent(groundHeadAtom);
// Prepare atom representing the rule body.
final RuleAtom bodyAtom = new RuleAtom(nonGroundRule, substitution);
// body representing atom already has an id.
if (atomStore.contains(bodyAtom)) {
// therefore all nogoods have already been created.
return emptyList();
}
final int bodyRepresentingLiteral = atomToLiteral(atomStore.putIfAbsent(bodyAtom));
final int headLiteral = atomToLiteral(atomStore.putIfAbsent(nonGroundRule.getHeadAtom().substitute(substitution)));
choiceRecorder.addHeadToBody(headId, atomOf(bodyRepresentingLiteral));
// Create a nogood for the head.
result.add(NoGood.headFirst(negateLiteral(headLiteral), bodyRepresentingLiteral));
final NoGood ruleBody = NoGood.fromBody(posLiterals, negLiterals, bodyRepresentingLiteral);
result.add(ruleBody);
// Nogoods such that the atom representing the body is true iff the body is true.
for (int j = 1; j < ruleBody.size(); j++) {
result.add(new NoGood(bodyRepresentingLiteral, negateLiteral(ruleBody.getLiteral(j))));
}
// If the rule head is unique, add support.
if (uniqueGroundRulePerGroundHead.contains(nonGroundRule)) {
result.add(NoGood.support(headLiteral, bodyRepresentingLiteral));
}
// If the body of the rule contains negation, add choices.
if (!negLiterals.isEmpty()) {
result.addAll(choiceRecorder.generateChoiceNoGoods(posLiterals, negLiterals, bodyRepresentingLiteral));
}
return result;
}
use of at.ac.tuwien.kr.alpha.core.atoms.RuleAtom 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()));
}
Aggregations