use of at.ac.tuwien.kr.alpha.api.programs.literals.Literal in project Alpha by alpha-asp.
the class LiteralInstantiator method instantiateBasicLiteral.
/**
* Calculates substitutions for a given literal that is not a {@link FixedInterpretationLiteral} or {@link EnumerationLiteral}.
* If applying the given partial substitution to the literal already grounds the literal, the resulting ground literal is verified based on
* this instantiators {@link LiteralInstantiationStrategy}. If the literal is only partially ground after applying the partial substitution,
* ground substitutions are looked up using the instantiators {@link LiteralInstantiationStrategy}. This method assumes that the partial
* substitution has <emph>not</emph> been applied to the passed literal.
*
* @param lit
* @param partialSubstitution
*/
private LiteralInstantiationResult instantiateBasicLiteral(Literal lit, Substitution partialSubstitution) {
LOGGER.trace("Instantiating basic literal: {}", lit);
List<ImmutablePair<Substitution, AssignmentStatus>> substitutions;
Literal substitutedLiteral = lit.substitute(partialSubstitution);
LOGGER.trace("Substituted literal is {}", substitutedLiteral);
if (substitutedLiteral.isGround()) {
LOGGER.trace("Literal {} is already ground, checking truth", substitutedLiteral);
// Lit seems to be a basic literal, so its satisfiability w.r.t.
// partialSubstitution is decided based on knownInstances by the
// instantiationStrategy.
AssignmentStatus truthForLiteral = this.instantiationStrategy.getTruthForGroundLiteral(substitutedLiteral);
if (truthForLiteral == AssignmentStatus.FALSE) {
return LiteralInstantiationResult.stopBinding();
} else {
return LiteralInstantiationResult.continueBinding(partialSubstitution, truthForLiteral);
}
} else {
LOGGER.trace("Handling non-ground literal {}", substitutedLiteral);
if (substitutedLiteral.isNegated()) {
return LiteralInstantiationResult.maybePushBack();
}
// Query instantiationStrategy for acceptable substitutions.
// Note: getAcceptedSubstitutions will only give substitutions where the
// resulting ground atom is true or unassigned, false atoms are internally
// discarded.
substitutions = this.instantiationStrategy.getAcceptedSubstitutions(substitutedLiteral, partialSubstitution);
LOGGER.trace("Got {} substitutions from instantiation strategy for {}", substitutions.size(), substitutedLiteral);
return substitutions.isEmpty() ? LiteralInstantiationResult.maybePushBack() : LiteralInstantiationResult.continueBinding(substitutions);
}
}
use of at.ac.tuwien.kr.alpha.api.programs.literals.Literal in project Alpha by alpha-asp.
the class AnalyzeUnjustified method explainUnjust.
private ReturnExplainUnjust explainUnjust(LitSet x, Assignment currentAssignment) {
padDepth += 2;
log("Begin explainUnjust(): {}", x);
Atom p = x.getAtom();
ReturnExplainUnjust ret = new ReturnExplainUnjust();
// Construct set of all 'rules' such that head unifies with p.
List<RuleAndUnifier> rulesUnifyingWithP = rulesHeadUnifyingWith(p);
log("Rules unifying with {} are {}", p, rulesUnifyingWithP);
rulesLoop: for (RuleAndUnifier ruleUnifier : rulesUnifyingWithP) {
Unifier sigma = ruleUnifier.unifier;
Set<Literal> bodyR = ruleUnifier.ruleBody;
Atom sigmaHr = ruleUnifier.originalHead.substitute(sigma);
log("Considering now: {}", ruleUnifier);
Set<Unifier> vN = new LinkedHashSet<>(x.getComplementSubstitutions());
for (Unifier sigmaN : vN) {
if (Unification.instantiate(p.substitute(sigmaN), sigmaHr) != null) {
log("Unifier is excluded by: {}", sigmaN);
continue rulesLoop;
}
}
Set<Unifier> vNp = new LinkedHashSet<>();
for (Unifier substitution : vN) {
Unifier merged = Unifier.mergeIntoLeft(substitution, sigma);
// Ignore inconsistent merges.
if (merged == null) {
continue;
}
vNp.add(merged);
}
log("Adapting N to N'. Original N is {}", vN);
log("Adapted N' is {}", vNp);
log("Searching for falsified negated literals in the body: {}", bodyR);
for (Literal lit : bodyR) {
if (!lit.isNegated()) {
continue;
}
Atom lb = lit.getAtom().substitute(sigma);
log("Found: {}, searching falsifying ground instances of {} (with unifier from the head) now.", lit, lb);
AssignedAtomsIterator assignedAtomsOverPredicate = getAssignedAtomsOverPredicate(lb.getPredicate());
while (assignedAtomsOverPredicate.hasNext()) {
Atom lg = assignedAtomsOverPredicate.next();
log("Considering: {}", lg);
if (atomStore.contains(lg)) {
int atomId = atomStore.get(lg);
if (!currentAssignment.getTruth(atomId).toBoolean()) {
log("{} is not assigned TRUE or MBT. Skipping.", lg);
continue;
}
}
// Note: in case the atom is not in the atomStore, it came from a fact and hence is true.
log("{} is TRUE or MBT.", lg);
Unifier sigmagb = Unification.unifyAtoms(lg, lb);
if (sigmagb == null) {
log("{} does not unify with {}", lg, lb);
continue;
}
log("Checking if {} is already covered.", lb);
boolean isCovered = false;
for (Unifier sigmaN : vN) {
if (Unification.instantiate(p.substitute(sigmaN), sigmaHr.substitute(sigmagb)) != null) {
log("{} is already covered by {}", lb, sigmaN);
isCovered = true;
break;
}
}
if (!isCovered) {
Unifier sigmacirc = new Unifier(sigma).extendWith(sigmagb);
vNp.add(sigmacirc);
log("Literal {} is not excluded and falsifies body literal {}", lg, lit);
ret.vL.add(lg.toLiteral());
log("Reasons extended by: {}", lg);
}
}
}
List<Literal> bodyPos = new ArrayList<>();
for (Literal literal : bodyR) {
if (!literal.isNegated()) {
bodyPos.add(literal);
}
}
log("Calling UnjustCover() for positive body.");
ret.vToDo.addAll(unjustCover(bodyPos, Collections.singleton(sigma), vNp, currentAssignment));
}
log("End explainUnjust().");
padDepth -= 2;
return ret;
}
use of at.ac.tuwien.kr.alpha.api.programs.literals.Literal in project Alpha by alpha-asp.
the class AnalyzeUnjustified method rulesHeadUnifyingWith.
private List<RuleAndUnifier> rulesHeadUnifyingWith(Atom p) {
List<RuleAndUnifier> rulesWithUnifier = new ArrayList<>();
Predicate predicate = p.getPredicate();
ArrayList<FactOrNonGroundRule> definingRulesAndFacts = new ArrayList<>();
// Get facts over the same predicate.
LinkedHashSet<Instance> factInstances = factsFromProgram.get(predicate);
if (factInstances != null) {
for (Instance factInstance : factInstances) {
definingRulesAndFacts.add(new FactOrNonGroundRule(factInstance));
}
}
HashSet<CompiledRule> rulesDefiningPredicate = programAnalysis.getPredicateDefiningRules().get(predicate);
if (rulesDefiningPredicate != null) {
for (CompiledRule nonGroundRule : rulesDefiningPredicate) {
definingRulesAndFacts.add(new FactOrNonGroundRule(nonGroundRule));
}
}
for (FactOrNonGroundRule factOrNonGroundRule : definingRulesAndFacts) {
boolean isNonGroundRule = factOrNonGroundRule.nonGroundRule != null;
Set<Literal> renamedBody;
Atom headAtom;
if (isNonGroundRule) {
// First rename all variables in the rule.
CompiledRule rule = factOrNonGroundRule.nonGroundRule.renameVariables("_" + renamingCounter++);
renamedBody = rule.getBody();
headAtom = rule.getHeadAtom();
} else {
// Create atom and empty rule body out of instance.
headAtom = Atoms.newBasicAtom(p.getPredicate(), factOrNonGroundRule.factInstance.terms);
renamedBody = Collections.emptySet();
}
// Unify rule head with literal to justify.
Unifier unifier = Unification.unifyAtoms(p, headAtom);
// Skip if unification failed.
if (unifier == null) {
continue;
}
rulesWithUnifier.add(new RuleAndUnifier(renamedBody, unifier, headAtom));
}
return rulesWithUnifier;
}
use of at.ac.tuwien.kr.alpha.api.programs.literals.Literal in project Alpha by alpha-asp.
the class AggregateRewritingRuleAnalysis method findBindingLiterals.
/**
* Recursively looks for literals in <code>searchScope</code> that bind the variables in the set
* <code>varsToBind</code>, i.e. any literal lit that has any variable var in question in its
* <code>bindingVariables</code> (i.e. lit assigns a value to var). Found binding literals are added to the set
* <code>boundSoFar</code>. If a literal has any of the desired variables as a binding variable, but also has other
* non-binding variables, the literals binding these are added to the set of desired variables for the next recursive
* call. Since {@link AggregateLiteral}s cannot report their non-binding variables by themselves, this method also needs
* a map of all aggregate literals and their global variables within the search scope.
*/
// Note: This algorithm has potentially exponential time complexity. Tuning potential definitely exists, but
// performance optimization seems non-trivial.
private static void findBindingLiterals(Set<VariableTerm> varsToBind, Set<VariableTerm> varsBoundSoFar, Set<Literal> foundSoFar, Set<Literal> searchScope, Map<AggregateLiteral, Set<VariableTerm>> aggregatesWithGlobalVars) {
int newlyBoundVars = 0;
Set<VariableTerm> furtherVarsToBind = new HashSet<>();
for (VariableTerm varToBind : varsToBind) {
for (Literal lit : searchScope) {
Set<VariableTerm> bindingVars = lit.getBindingVariables();
Set<VariableTerm> nonBindingVars = (lit instanceof AggregateLiteral) ? aggregatesWithGlobalVars.get((AggregateLiteral) lit) : lit.getNonBindingVariables();
if (bindingVars.contains(varToBind)) {
varsBoundSoFar.add(varToBind);
foundSoFar.add(lit);
newlyBoundVars++;
for (VariableTerm nonBindingVar : nonBindingVars) {
if (!varsBoundSoFar.contains(nonBindingVar)) {
furtherVarsToBind.add(nonBindingVar);
}
}
}
}
}
if (newlyBoundVars == 0 && !varsToBind.isEmpty()) {
// screaming than producing a stack overflow ;-)
throw new IllegalStateException("Couldn't find any literals binding variables: " + varsToBind + " in search scope " + searchScope);
}
if (!furtherVarsToBind.isEmpty()) {
// As long as we find variables we still need to bind, repeat with the new set of variables to bind.
findBindingLiterals(furtherVarsToBind, varsBoundSoFar, foundSoFar, searchScope, aggregatesWithGlobalVars);
}
}
use of at.ac.tuwien.kr.alpha.api.programs.literals.Literal in project Alpha by alpha-asp.
the class NaiveGrounder method initializeFactsAndRules.
private void initializeFactsAndRules() {
// Initialize all facts.
for (Atom fact : program.getFacts()) {
final Predicate predicate = fact.getPredicate();
// Record predicate
workingMemory.initialize(predicate);
}
// Register internal atoms.
workingMemory.initialize(RuleAtom.PREDICATE);
workingMemory.initialize(ChoiceAtom.OFF);
workingMemory.initialize(ChoiceAtom.ON);
// Initialize rules and constraints in working memory.
for (CompiledRule nonGroundRule : program.getRulesById().values()) {
// Create working memories for all predicates occurring in the rule.
for (Predicate predicate : nonGroundRule.getOccurringPredicates()) {
// FIXME: this also contains interval/builtin predicates that are not needed.
workingMemory.initialize(predicate);
}
// If the rule has fixed ground instantiations, it is not registered but grounded once like facts.
if (nonGroundRule.getGroundingInfo().hasFixedInstantiation()) {
fixedRules.add(nonGroundRule);
continue;
}
// Register each starting literal at the corresponding working memory.
for (Literal literal : nonGroundRule.getGroundingInfo().getStartingLiterals()) {
registerLiteralAtWorkingMemory(literal, nonGroundRule);
}
}
}
Aggregations