Search in sources :

Example 41 with VariableTerm

use of at.ac.tuwien.kr.alpha.api.terms.VariableTerm in project Alpha by alpha-asp.

the class VariableEqualityRemoval method findAndReplaceVariableEquality.

private Rule<Head> findAndReplaceVariableEquality(Rule<Head> rule) {
    // Collect all equal variables.
    HashMap<VariableTerm, HashSet<VariableTerm>> variableToEqualVariables = new LinkedHashMap<>();
    HashSet<Literal> equalitiesToRemove = new HashSet<>();
    for (Literal bodyElement : rule.getBody()) {
        if (!(bodyElement instanceof ComparisonLiteral)) {
            continue;
        }
        ComparisonLiteral comparisonLiteral = (ComparisonLiteral) bodyElement;
        if (!comparisonLiteral.isNormalizedEquality()) {
            continue;
        }
        if (comparisonLiteral.getTerms().get(0) instanceof VariableTerm && comparisonLiteral.getTerms().get(1) instanceof VariableTerm) {
            VariableTerm leftVariable = (VariableTerm) comparisonLiteral.getTerms().get(0);
            VariableTerm rightVariable = (VariableTerm) comparisonLiteral.getTerms().get(1);
            HashSet<VariableTerm> leftEqualVariables = variableToEqualVariables.get(leftVariable);
            HashSet<VariableTerm> rightEqualVariables = variableToEqualVariables.get(rightVariable);
            if (leftEqualVariables == null && rightEqualVariables == null) {
                HashSet<VariableTerm> equalVariables = new LinkedHashSet<>(Arrays.asList(leftVariable, rightVariable));
                variableToEqualVariables.put(leftVariable, equalVariables);
                variableToEqualVariables.put(rightVariable, equalVariables);
            }
            if (leftEqualVariables == null && rightEqualVariables != null) {
                rightEqualVariables.add(leftVariable);
                variableToEqualVariables.put(leftVariable, rightEqualVariables);
            }
            if (leftEqualVariables != null && rightEqualVariables == null) {
                leftEqualVariables.add(rightVariable);
                variableToEqualVariables.put(rightVariable, leftEqualVariables);
            }
            if (leftEqualVariables != null && rightEqualVariables != null) {
                leftEqualVariables.addAll(rightEqualVariables);
                for (VariableTerm rightEqualVariable : rightEqualVariables) {
                    variableToEqualVariables.put(rightEqualVariable, leftEqualVariables);
                }
            }
            equalitiesToRemove.add(comparisonLiteral);
        }
    }
    if (variableToEqualVariables.isEmpty()) {
        // Skip rule if there is no equality between variables.
        return rule;
    }
    List<Literal> rewrittenBody = new ArrayList<>(rule.getBody());
    if (!rule.isConstraint() && rule.getHead() instanceof DisjunctiveHead) {
        throw new UnsupportedOperationException("VariableEqualityRemoval cannot be applied to rule with DisjunctiveHead, yet.");
    }
    NormalHead rewrittenHead = rule.isConstraint() ? null : Heads.newNormalHead(((NormalHead) rule.getHead()).getAtom());
    // Use substitution for actual replacement.
    Unifier replacementSubstitution = new Unifier();
    // For each set of equal variables, take the first variable and replace all others by it.
    for (Map.Entry<VariableTerm, HashSet<VariableTerm>> variableEqualityEntry : variableToEqualVariables.entrySet()) {
        VariableTerm variableToReplace = variableEqualityEntry.getKey();
        VariableTerm replacementVariable = variableEqualityEntry.getValue().iterator().next();
        if (variableToReplace == replacementVariable) {
            continue;
        }
        replacementSubstitution.put(variableToReplace, replacementVariable);
    }
    // Replace/Substitute in each literal every term where one of the common variables occurs.
    Iterator<Literal> bodyIterator = rewrittenBody.iterator();
    while (bodyIterator.hasNext()) {
        Literal literal = bodyIterator.next();
        if (equalitiesToRemove.contains(literal)) {
            bodyIterator.remove();
        }
        for (int i = 0; i < literal.getTerms().size(); i++) {
            Term replaced = literal.getTerms().get(i).substitute(replacementSubstitution);
            literal.getTerms().set(i, replaced);
        }
    }
    // Replace variables in head.
    if (rewrittenHead != null) {
        Atom headAtom = rewrittenHead.getAtom();
        for (int i = 0; i < headAtom.getTerms().size(); i++) {
            Term replaced = headAtom.getTerms().get(i).substitute(replacementSubstitution);
            headAtom.getTerms().set(i, replaced);
        }
    }
    return new BasicRule(rewrittenHead, rewrittenBody);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) BasicRule(at.ac.tuwien.kr.alpha.core.rules.BasicRule) ArrayList(java.util.ArrayList) DisjunctiveHead(at.ac.tuwien.kr.alpha.api.rules.heads.DisjunctiveHead) Term(at.ac.tuwien.kr.alpha.api.terms.Term) VariableTerm(at.ac.tuwien.kr.alpha.api.terms.VariableTerm) Atom(at.ac.tuwien.kr.alpha.api.programs.atoms.Atom) LinkedHashMap(java.util.LinkedHashMap) NormalHead(at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead) Literal(at.ac.tuwien.kr.alpha.api.programs.literals.Literal) ComparisonLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral) VariableTerm(at.ac.tuwien.kr.alpha.api.terms.VariableTerm) ComparisonLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) Unifier(at.ac.tuwien.kr.alpha.commons.substitutions.Unifier) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 42 with VariableTerm

use of at.ac.tuwien.kr.alpha.api.terms.VariableTerm 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 43 with VariableTerm

use of at.ac.tuwien.kr.alpha.api.terms.VariableTerm in project Alpha by alpha-asp.

the class Unification method unifyAtoms.

private static Unifier unifyAtoms(Atom left, Atom right, boolean keepLeftAsIs) {
    Set<VariableTerm> leftOccurringVariables = left.getOccurringVariables();
    Set<VariableTerm> rightOccurringVaribles = right.getOccurringVariables();
    boolean leftSmaller = leftOccurringVariables.size() < rightOccurringVaribles.size();
    Set<VariableTerm> smallerSet = leftSmaller ? leftOccurringVariables : rightOccurringVaribles;
    Set<VariableTerm> largerSet = leftSmaller ? rightOccurringVaribles : leftOccurringVariables;
    for (VariableTerm variableTerm : smallerSet) {
        if (largerSet.contains(variableTerm)) {
            throw oops("Left and right atom share variables.");
        }
    }
    Unifier mgu = new Unifier();
    if (!left.getPredicate().equals(right.getPredicate())) {
        return null;
    }
    for (int i = 0; i < left.getPredicate().getArity(); i++) {
        final Term leftTerm = left.getTerms().get(i);
        final Term rightTerm = right.getTerms().get(i);
        if (!unifyTerms(leftTerm, rightTerm, mgu, keepLeftAsIs)) {
            return null;
        }
    }
    return mgu;
}
Also used : VariableTerm(at.ac.tuwien.kr.alpha.api.terms.VariableTerm) VariableTerm(at.ac.tuwien.kr.alpha.api.terms.VariableTerm) Term(at.ac.tuwien.kr.alpha.api.terms.Term) ArithmeticTerm(at.ac.tuwien.kr.alpha.api.terms.ArithmeticTerm) FunctionTerm(at.ac.tuwien.kr.alpha.api.terms.FunctionTerm) Unifier(at.ac.tuwien.kr.alpha.commons.substitutions.Unifier)

Example 44 with VariableTerm

use of at.ac.tuwien.kr.alpha.api.terms.VariableTerm in project Alpha by alpha-asp.

the class UnifierTest method extendUnifier.

@Test
public void extendUnifier() {
    VariableTerm varX = Terms.newVariable("X");
    VariableTerm varY = Terms.newVariable("Y");
    Unifier sub1 = new Unifier();
    sub1.put(varX, varY);
    Unifier sub2 = new Unifier();
    sub2.put(varY, Terms.newConstant("a"));
    sub1.extendWith(sub2);
    BasicAtom atom1 = parseAtom("p(X)");
    Atom atomSubstituted = atom1.substitute(sub1);
    assertEquals(Terms.newConstant("a"), atomSubstituted.getTerms().get(0));
}
Also used : VariableTerm(at.ac.tuwien.kr.alpha.api.terms.VariableTerm) BasicAtom(at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom) Unifier(at.ac.tuwien.kr.alpha.commons.substitutions.Unifier) BasicAtom(at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom) Atom(at.ac.tuwien.kr.alpha.api.programs.atoms.Atom) Test(org.junit.jupiter.api.Test)

Example 45 with VariableTerm

use of at.ac.tuwien.kr.alpha.api.terms.VariableTerm in project Alpha by alpha-asp.

the class Substitutions method fromString.

public static Substitution fromString(String str) {
    String bare = str.substring(1, str.length() - 1);
    String[] assignments = bare.split(",");
    BasicSubstitution ret = new BasicSubstitution();
    for (String assignment : assignments) {
        String[] keyVal = assignment.split("->");
        VariableTerm variable = Terms.newVariable(keyVal[0]);
        Term assignedTerm = PROGRAM_PART_PARSER.parseTerm(keyVal[1]);
        ret.put(variable, assignedTerm);
    }
    return ret;
}
Also used : BasicSubstitution(at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution) VariableTerm(at.ac.tuwien.kr.alpha.api.terms.VariableTerm) VariableTerm(at.ac.tuwien.kr.alpha.api.terms.VariableTerm) Term(at.ac.tuwien.kr.alpha.api.terms.Term)

Aggregations

VariableTerm (at.ac.tuwien.kr.alpha.api.terms.VariableTerm)45 Term (at.ac.tuwien.kr.alpha.api.terms.Term)25 Literal (at.ac.tuwien.kr.alpha.api.programs.literals.Literal)18 Test (org.junit.jupiter.api.Test)13 ArrayList (java.util.ArrayList)12 HashSet (java.util.HashSet)10 BasicSubstitution (at.ac.tuwien.kr.alpha.commons.substitutions.BasicSubstitution)9 AggregateLiteral (at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral)8 Substitution (at.ac.tuwien.kr.alpha.api.grounder.Substitution)6 ArithmeticTerm (at.ac.tuwien.kr.alpha.api.terms.ArithmeticTerm)6 ConstantTerm (at.ac.tuwien.kr.alpha.api.terms.ConstantTerm)6 FunctionTerm (at.ac.tuwien.kr.alpha.api.terms.FunctionTerm)6 Unifier (at.ac.tuwien.kr.alpha.commons.substitutions.Unifier)6 IntervalTerm (at.ac.tuwien.kr.alpha.commons.terms.IntervalTerm)6 Map (java.util.Map)6 Atom (at.ac.tuwien.kr.alpha.api.programs.atoms.Atom)5 NormalHead (at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead)5 Predicate (at.ac.tuwien.kr.alpha.api.programs.Predicate)4 AggregateAtom (at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom)4 BasicAtom (at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom)4