Search in sources :

Example 61 with Literal

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);
    }
}
Also used : ImmutablePair(org.apache.commons.lang3.tuple.ImmutablePair) IntervalLiteral(at.ac.tuwien.kr.alpha.core.atoms.IntervalLiteral) FixedInterpretationLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.FixedInterpretationLiteral) EnumerationLiteral(at.ac.tuwien.kr.alpha.core.atoms.EnumerationLiteral) ExternalLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.ExternalLiteral) Literal(at.ac.tuwien.kr.alpha.api.programs.literals.Literal) ComparisonLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral)

Example 62 with Literal

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;
}
Also used : HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) Literal(at.ac.tuwien.kr.alpha.api.programs.literals.Literal) ComparisonLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral) ArrayList(java.util.ArrayList) List(java.util.List) BasicAtom(at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom) Atom(at.ac.tuwien.kr.alpha.api.programs.atoms.Atom) Unifier(at.ac.tuwien.kr.alpha.commons.substitutions.Unifier)

Example 63 with Literal

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;
}
Also used : Instance(at.ac.tuwien.kr.alpha.commons.substitutions.Instance) ArrayList(java.util.ArrayList) BasicAtom(at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom) Atom(at.ac.tuwien.kr.alpha.api.programs.atoms.Atom) Predicate(at.ac.tuwien.kr.alpha.api.programs.Predicate) CompiledRule(at.ac.tuwien.kr.alpha.core.rules.CompiledRule) Literal(at.ac.tuwien.kr.alpha.api.programs.literals.Literal) ComparisonLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral) Unifier(at.ac.tuwien.kr.alpha.commons.substitutions.Unifier)

Example 64 with Literal

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);
    }
}
Also used : AggregateLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral) Literal(at.ac.tuwien.kr.alpha.api.programs.literals.Literal) AggregateLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral) VariableTerm(at.ac.tuwien.kr.alpha.api.terms.VariableTerm) HashSet(java.util.HashSet)

Example 65 with Literal

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);
        }
    }
}
Also used : CompiledRule(at.ac.tuwien.kr.alpha.core.rules.CompiledRule) Literal(at.ac.tuwien.kr.alpha.api.programs.literals.Literal) ChoiceAtom(at.ac.tuwien.kr.alpha.core.atoms.ChoiceAtom) Atom(at.ac.tuwien.kr.alpha.api.programs.atoms.Atom) RuleAtom(at.ac.tuwien.kr.alpha.core.atoms.RuleAtom) Predicate(at.ac.tuwien.kr.alpha.api.programs.Predicate)

Aggregations

Literal (at.ac.tuwien.kr.alpha.api.programs.literals.Literal)82 Test (org.junit.jupiter.api.Test)42 VariableTerm (at.ac.tuwien.kr.alpha.api.terms.VariableTerm)20 ArrayList (java.util.ArrayList)20 AggregateLiteral (at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral)17 Atom (at.ac.tuwien.kr.alpha.api.programs.atoms.Atom)16 Substitution (at.ac.tuwien.kr.alpha.api.grounder.Substitution)14 Predicate (at.ac.tuwien.kr.alpha.api.programs.Predicate)14 BasicAtom (at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom)14 BasicSubstitution (at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution)13 Map (java.util.Map)12 Head (at.ac.tuwien.kr.alpha.api.rules.heads.Head)11 CompiledProgram (at.ac.tuwien.kr.alpha.core.programs.CompiledProgram)11 CompiledRule (at.ac.tuwien.kr.alpha.core.rules.CompiledRule)10 HashSet (java.util.HashSet)10 ComparisonLiteral (at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral)9 Instance (at.ac.tuwien.kr.alpha.commons.substitutions.Instance)9 LinkedHashSet (java.util.LinkedHashSet)8 List (java.util.List)8 Term (at.ac.tuwien.kr.alpha.api.terms.Term)7