use of at.ac.tuwien.kr.alpha.core.solver.TrailAssignment in project Alpha by alpha-asp.
the class NaiveGrounderTest method testDeadEnd.
/**
* Tests the method {@link NaiveGrounder#getGroundInstantiations(InternalRule, RuleGroundingOrder, Substitution, Assignment)} on a
* predefined program:
* <code>
* p1(1). q1(1). <br/>
* x :- p1(X), p2(X), q1(Y), q2(Y). <br/>
* p2(X) :- something(X). <br/>
* q2(X) :- something(X). <br/>
* </code>
* Given one grounding order {@code groundingOrder} for the first rule in this program which starts with
* the literal whose predicate name is {@code predicateNameOfStartingLiteral} and a substitution substituting
* the variable in this literal by 1 it is attempted to ground the rule.
* It is then asserted that ground instantiations are produced if and only if {@code expectNoGoods} is true.
*
* @param predicateNameOfStartingLiteral the predicate name of the starting literal, either "p1" or "q1".
* @param groundingOrder a grounding order for the first rule in the predefined program that starts with the literal
* whose predicate name is {@code predicateNameOfStartingLiteral}.
* @param expectNoGoods {@code true} iff ground instantiations are expected to be produced under the conditions
* described above.
*/
private void testDeadEnd(String predicateNameOfStartingLiteral, RuleGroundingOrderImpl groundingOrder, boolean expectNoGoods) {
String aspStr = "p1(1). q1(1). " + "x :- p1(X), p2(X), q1(Y), q2(Y). " + "p2(X) :- something(X). " + "q2(X) :- something(X). ";
CompiledProgram program = InternalProgram.fromNormalProgram(NORMALIZE_TRANSFORM.apply(PROGRAM_PARSER.parse(aspStr)));
AtomStore atomStore = new AtomStoreImpl();
NaiveGrounder grounder = (NaiveGrounder) GrounderFactory.getInstance("naive", program, atomStore, p -> true, GrounderHeuristicsConfiguration.permissive(), true);
CompiledRule nonGroundRule = grounder.getNonGroundRule(0);
String strLiteral = "p1".equals(predicateNameOfStartingLiteral) ? "p1(X)" : "p1(Y)";
final Literal startingLiteral = PROGRAM_PART_PARSER.parseLiteral(strLiteral);
((RuleGroundingInfoImpl) nonGroundRule.getGroundingInfo()).groundingOrders.put(startingLiteral, groundingOrder);
grounder.bootstrap();
TrailAssignment currentAssignment = new TrailAssignment(atomStore);
final Substitution subst1 = BasicSubstitution.specializeSubstitution(startingLiteral, new Instance(Terms.newConstant(1)), BasicSubstitution.EMPTY_SUBSTITUTION);
final BindingResult bindingResult = grounder.getGroundInstantiations(nonGroundRule, groundingOrder, subst1, currentAssignment);
assertEquals(expectNoGoods, bindingResult.size() > 0);
}
use of at.ac.tuwien.kr.alpha.core.solver.TrailAssignment in project Alpha by alpha-asp.
the class NaiveGrounderTest method addAtomsToWorkingMemoryWithoutChangingTheAssignment.
/**
* Adds atoms {@code atomIDs} to {@code grounder}'s working memory without changing the assignment.
* This is achieved by creating a temporary assignment on {@code atomStore} in which those atoms are assigned true
* and using this temporary assignment to update the grounder's working memory.
*/
private void addAtomsToWorkingMemoryWithoutChangingTheAssignment(AtomStore atomStore, NaiveGrounder grounder, int[] atomIDs) {
TrailAssignment temporaryAssignment = new TrailAssignment(atomStore);
temporaryAssignment.growForMaxAtomId();
for (int b : atomIDs) {
temporaryAssignment.assign(b, ThriceTruth.TRUE);
}
grounder.updateAssignment(temporaryAssignment.getNewPositiveAssignmentsIterator());
}
use of at.ac.tuwien.kr.alpha.core.solver.TrailAssignment in project Alpha by alpha-asp.
the class NaiveGrounderTest method testIfGrounderGroundsRule.
/**
* 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 {@code b(1)} is assigned
* {@code bTruth}.
* It is asserted that ground instantiations are produced if and only if {@code expectNoGoods} is true.
*/
private void testIfGrounderGroundsRule(ASPCore2Program program, int ruleID, Literal startingLiteral, int startingInstance, ThriceTruth bTruth, boolean expectNoGoods) {
CompiledProgram internalPrg = InternalProgram.fromNormalProgram(NORMALIZE_TRANSFORM.apply(program));
AtomStore atomStore = new AtomStoreImpl();
TrailAssignment currentAssignment = new TrailAssignment(atomStore);
NaiveGrounder grounder = (NaiveGrounder) GrounderFactory.getInstance("naive", internalPrg, atomStore, p -> true, GrounderHeuristicsConfiguration.permissive(), true);
int b = atomStore.putIfAbsent(atom("b", 1));
currentAssignment.growForMaxAtomId();
currentAssignment.assign(b, bTruth);
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);
}
use of at.ac.tuwien.kr.alpha.core.solver.TrailAssignment in project Alpha by alpha-asp.
the class GroundConflictNoGoodLearner method analyzeTrailBased.
private ConflictAnalysisResult analyzeTrailBased(Antecedent conflictReason) {
LOGGER.trace("Analyzing trail based.");
if (assignment.getDecisionLevel() == 0) {
LOGGER.trace("Conflict on decision level 0.");
return ConflictAnalysisResult.UNSAT;
}
int numLiteralsInConflictLevel = 0;
List<Integer> resolutionLiterals = new ArrayList<>();
List<Integer> resolutionAtoms = new ArrayList<>();
int currentDecisionLevel = assignment.getDecisionLevel();
// NOTE: other solvers use a global array for seen atoms, this might be slightly faster (initial tests with local arrays showed no significant improvement).
Set<Integer> seenAtoms = new HashSet<>();
// Since trail contains 2 entries for MBT->TRUE assigned atoms, explicitly record which seen atoms have ben processed to avoid processing seen atoms twice.
Set<Integer> processedAtoms = new HashSet<>();
int[] currentConflictReason = conflictReason.getReasonLiterals();
int backjumpLevel = -1;
conflictReason.bumpActivity();
TrailAssignment.TrailBackwardsWalker trailWalker = ((TrailAssignment) assignment).getTrailBackwardsWalker();
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Current trail is: {}", trailWalker);
LOGGER.trace("Violated nogood is: {}", reasonsToString(conflictReason.getReasonLiterals()));
}
int nextAtom = -1;
do {
// Add current conflict reasons; only add those of lower decision levels, since from current one, only the 1UIP literal will be added.
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Atom {} implied by {}, resolving with that nogood", nextAtom, reasonsToString(currentConflictReason));
}
for (int literal : currentConflictReason) {
// Seen atoms have already been dealt with.
if (!seenAtoms.contains(atomOf(literal))) {
seenAtoms.add(atomOf(literal));
int literalDecisionLevel = assignment.getWeakDecisionLevel(atomOf(literal));
if (literalDecisionLevel == currentDecisionLevel) {
numLiteralsInConflictLevel++;
} else {
resolutionLiterals.add(literal);
if (literalDecisionLevel > backjumpLevel) {
backjumpLevel = literalDecisionLevel;
}
}
resolutionAtoms.add(atomOf(literal));
}
}
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("LiteralsInConflictLevel now: {}", numLiteralsInConflictLevel);
LOGGER.trace("Seen atoms are {}.", seenAtoms);
LOGGER.trace("Intermediate learned literals: {}", reasonsToString(resolutionLiterals));
}
// Find next literal, i.e. first from top of trail that has been seen but is not yet processed, also skip atoms whose TRUE assignment is on current level but their MBT/weak assignment is lower.
do {
int nextLiteral = trailWalker.getNextLowerLiteral();
nextAtom = atomOf(nextLiteral);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Next literal on trail is: {}", isPositive(nextLiteral) ? "+" + nextAtom : "-" + nextAtom);
}
} while (assignment.getWeakDecisionLevel(nextAtom) != currentDecisionLevel || !seenAtoms.contains(nextAtom) || processedAtoms.contains(nextAtom));
Antecedent impliedBy = assignment.getImpliedBy(nextAtom);
if (impliedBy != null) {
currentConflictReason = impliedBy.getReasonLiterals();
impliedBy.bumpActivity();
}
processedAtoms.add(nextAtom);
} while (numLiteralsInConflictLevel-- > 1);
// Add the 1UIP literal.
resolutionLiterals.add(atomToLiteral(nextAtom, assignment.getTruth(nextAtom).toBoolean()));
int[] learnedLiterals = minimizeLearnedLiterals(resolutionLiterals, seenAtoms);
NoGood learnedNoGood = NoGood.learnt(learnedLiterals);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Learned NoGood is: {}", atomStore.noGoodToString(learnedNoGood));
}
int backjumpingDecisionLevel = computeBackjumpingDecisionLevel(learnedNoGood);
if (backjumpingDecisionLevel < 0) {
// Due to out-of-order assigned literals, the learned nogood may be not assigning.
backjumpingDecisionLevel = computeConflictFreeBackjumpingLevel(learnedNoGood);
if (backjumpingDecisionLevel < 0) {
return ConflictAnalysisResult.UNSAT;
}
}
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Backjumping decision level: {}", backjumpingDecisionLevel);
}
return new ConflictAnalysisResult(learnedNoGood, backjumpingDecisionLevel, resolutionAtoms, computeLBD(learnedLiterals));
}
use of at.ac.tuwien.kr.alpha.core.solver.TrailAssignment in project Alpha by alpha-asp.
the class BerkMinTest method setUp.
@BeforeEach
public void setUp() {
AtomStore atomStore = new AtomStoreImpl();
TestUtils.fillAtomStore(atomStore, 2);
WritableAssignment assignment = new TrailAssignment(atomStore);
assignment.growForMaxAtomId();
this.berkmin = new BerkMin(assignment, new PseudoChoiceManager(assignment, new NaiveNoGoodStore(assignment)), new Random());
}
Aggregations