use of at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom in project Alpha by alpha-asp.
the class InternalRule method renameVariables.
/**
* Returns a new Rule that is equal to this one except that all variables are renamed to have the newVariablePostfix
* appended.
*
* @param newVariablePostfix
* @return
*/
@Override
public InternalRule renameVariables(String newVariablePostfix) {
List<VariableTerm> occurringVariables = new ArrayList<>();
BasicAtom headAtom = this.getHeadAtom();
occurringVariables.addAll(headAtom.getOccurringVariables());
for (Literal literal : this.getBody()) {
occurringVariables.addAll(literal.getOccurringVariables());
}
Unifier variableReplacement = new Unifier();
for (VariableTerm occurringVariable : occurringVariables) {
final String newVariableName = occurringVariable.toString() + newVariablePostfix;
variableReplacement.put(occurringVariable, Terms.newVariable(newVariableName));
}
BasicAtom renamedHeadAtom = headAtom.substitute(variableReplacement);
ArrayList<Literal> renamedBody = new ArrayList<>(this.getBody().size());
for (Literal literal : this.getBody()) {
renamedBody.add(literal.substitute(variableReplacement));
}
return new InternalRule(Heads.newNormalHead(renamedHeadAtom), renamedBody);
}
use of at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom in project Alpha by alpha-asp.
the class RuleGroundingInfoImpl method computeStartingLiterals.
/**
* Computes starting literals and indicates whether there is a fixed ground instantiation for this rule.
*
* @return true iff the rule has a fixed ground instantiation.
*/
private boolean computeStartingLiterals() {
LinkedHashSet<Literal> fixedStartingLiterals = new LinkedHashSet<>();
LinkedHashSet<Literal> ordinaryStartingLiterals = new LinkedHashSet<>();
// If the rule is ground, every body literal is a starting literal and the ground instantiation is fixed.
if (internalRule.isGround()) {
startingLiterals = new LinkedList<>(internalRule.getBody());
return true;
}
// Check each literal in the rule body whether it is eligible.
for (Literal literal : internalRule.getBody()) {
// Only literals that need no variables already bound can start grounding.
if (literal.getNonBindingVariables().size() != 0) {
continue;
}
if (literal.getAtom() instanceof BasicAtom && !literal.isNegated()) {
// Positive BasicAtom is the main/ordinary case.
ordinaryStartingLiterals.add(literal);
} else {
// If literal is no positive BasicAtom but requires no bound variables,
// it can be the starting literal for some (fixed) instantiation.
fixedStartingLiterals.add(literal);
}
}
// instantiation literals and those are starting for the one-time grounding.
if (!ordinaryStartingLiterals.isEmpty()) {
startingLiterals = new LinkedList<>(ordinaryStartingLiterals);
return false;
} else if (!fixedStartingLiterals.isEmpty()) {
startingLiterals = new LinkedList<>(fixedStartingLiterals);
return true;
} else {
throw new RuntimeException("Unsafe rule encountered: " + internalRule);
}
}
use of at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom in project Alpha by alpha-asp.
the class AnalyzeUnjustified method analyze.
public Set<Literal> analyze(int atomToJustify, Assignment currentAssignment) {
padDepth = 0;
Atom atom = atomStore.get(atomToJustify);
if (!(atom instanceof BasicAtom)) {
throw oops("Starting atom must be a BasicAtom, but received: " + atom + " of type: " + atom.getClass());
}
// @formatter:off
// Calling code must make sure it is a BasicAtom and take precautions.
// Potential solutions:
// If atom instanceof RuleAtom and atom is MBT, then the corresponding rule body has a BasicAtom that is MBT.
// If atom instanceof ChoiceAtom and atom is MBT, then the corresponding rule body has a BasicAtom that is MBT.
// If atom instanceof RuleAtom and atom is FALSE, then this comes from a violated constraint in the end and the corresponding rule body can be taken as the single rule deriving the RuleAtom.
// @formatter:on
assignedAtoms = new LinkedHashMap<>();
for (int i = 1; i <= atomStore.getMaxAtomId(); i++) {
ThriceTruth truth = currentAssignment.getTruth(i);
if (truth == null) {
continue;
}
Atom assignedAtom = atomStore.get(i);
assignedAtoms.putIfAbsent(assignedAtom.getPredicate(), new ArrayList<>());
assignedAtoms.get(assignedAtom.getPredicate()).add(assignedAtom);
}
return analyze((BasicAtom) atom, currentAssignment);
}
use of at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom in project Alpha by alpha-asp.
the class AnalyzeUnjustified method unjustCover.
private Set<LitSet> unjustCover(List<Literal> vB, Set<Unifier> vY, Set<Unifier> vN, Assignment currentAssignment) {
padDepth += 2;
log("Begin UnjustCoverFixed()");
log("Finding unjustified body literals in: {} / {} excluded {}", vB, vY, vN);
Set<LitSet> ret = new LinkedHashSet<>();
if (vB.isEmpty() || vY.isEmpty()) {
log("End unjustCover().");
padDepth -= 2;
return Collections.emptySet();
}
int chosenLiteralPos = 0;
// Find a body literal that is not a ComparisonLiteral, because these do not generate/have atoms assigned.
for (int i = 0; i < vB.size(); i++) {
if (!(vB.get(i) instanceof ComparisonLiteral)) {
// TODO: Should this be FixedInterpretationLiteral instead??
chosenLiteralPos = i;
break;
}
}
Atom b = vB.get(chosenLiteralPos).getAtom();
log("Picked literal from body is: {}", b);
for (Unifier sigmaY : vY) {
Atom bSigmaY = b.substitute(sigmaY);
log("Treating substitution for: {}", bSigmaY);
Set<Unifier> vYp = new LinkedHashSet<>();
log("Checking atoms over predicate: {}", b.getPredicate());
AssignedAtomsIterator assignedAtomsOverPredicate = getAssignedAtomsOverPredicate(b.getPredicate());
atomLoop: while (assignedAtomsOverPredicate.hasNext()) {
Atom atom = assignedAtomsOverPredicate.next();
// Check that atom is justified/true.
log("Checking atom: {}", atom);
if (atomStore.contains(atom)) {
int atomId = atomStore.get(atom);
if (currentAssignment.getTruth(atomId) != ThriceTruth.TRUE) {
log("Atom is not TRUE. Skipping.");
continue;
}
}
// Note: in case the atom is not in the atomStore, it came from a fact and hence is true.
Unifier sigma = Unification.instantiate(b, atom);
if (sigma == null) {
log("Atom does not unify with picked body literal.");
continue;
}
Atom bSigma = b.substitute(sigma);
if (!bSigma.isGround()) {
throw oops("Resulting atom is not ground.");
}
Set<VariableTerm> variablesOccurringInSigma = sigma.getMappedVariables();
if (Unification.instantiate(bSigmaY, bSigma) != null) {
for (Unifier sigmaN : vN) {
ArrayList<Term> occurringVariables = new ArrayList<>(variablesOccurringInSigma);
occurringVariables.addAll(sigmaN.getMappedVariables());
BasicAtom genericAtom = Atoms.newBasicAtom(Predicates.getPredicate("_", occurringVariables.size(), true), occurringVariables);
Atom genericSubstituted = genericAtom.substitute(sigmaN).renameVariables("_analyzeTest");
if (Unification.instantiate(genericSubstituted, genericAtom.substitute(sigma)) != null) {
log("Atom {} is excluded by: {} via {}", genericSubstituted, sigmaN, sigma);
continue atomLoop;
}
}
log("Adding corresponding substitution to Y': {}", sigma);
vYp.add(sigma);
}
}
log("Unjustified body literals: {}", vYp);
Set<Unifier> vYpUN = new LinkedHashSet<>();
vYpUN.addAll(vYp);
vYpUN.addAll(vN);
LitSet toJustify = new LitSet(bSigmaY, vYpUN);
if (!toJustify.coversNothing()) {
log("New litset to do: {}", toJustify);
ret.add(toJustify);
} else {
log("Generated LitSet covers nothing. Ignoring: {}", toJustify);
}
ArrayList<Literal> newB = new ArrayList<>(vB);
newB.remove(chosenLiteralPos);
ret.addAll(unjustCover(newB, vYp, vN, currentAssignment));
log("Literal set(s) to treat: {}", ret);
}
log("End unjustCover().");
padDepth -= 2;
return ret;
}
use of at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom 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