Search in sources :

Example 1 with ComparisonLiteral

use of at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral in project Alpha by alpha-asp.

the class IntervalTermToIntervalAtom method rewriteLiteral.

/**
 * Replaces every IntervalTerm by a new variable and returns a mapping of the replaced VariableTerm -> IntervalTerm.
 *
 * @return the rewritten literal or null if the literal should be dropped from the final rule.
 */
private static Literal rewriteLiteral(Literal lit, Map<VariableTerm, IntervalTerm> intervalReplacement) {
    // final rule.
    if (lit instanceof ComparisonLiteral && ((ComparisonLiteral) lit).isNormalizedEquality()) {
        ComparisonAtom equalityLiteral = (ComparisonAtom) lit.getAtom();
        if (equalityLiteral.getTerms().get(0) instanceof VariableTerm && equalityLiteral.getTerms().get(1) instanceof IntervalTerm) {
            // Literal is of the form "X = A .. B".
            intervalReplacement.put((VariableTerm) equalityLiteral.getTerms().get(0), (IntervalTerm) equalityLiteral.getTerms().get(1));
            return null;
        }
        if (equalityLiteral.getTerms().get(1) instanceof VariableTerm && equalityLiteral.getTerms().get(0) instanceof IntervalTerm) {
            // Literal is of the form "A .. B = X".
            intervalReplacement.put((VariableTerm) equalityLiteral.getTerms().get(1), (IntervalTerm) equalityLiteral.getTerms().get(0));
            return null;
        }
    }
    Atom atom = lit.getAtom();
    List<Term> termList = new ArrayList<>(atom.getTerms());
    boolean didChange = false;
    for (int i = 0; i < termList.size(); i++) {
        Term term = termList.get(i);
        if (term instanceof IntervalTerm) {
            VariableTerm replacementVariable = Terms.newVariable(INTERVAL_VARIABLE_PREFIX + intervalReplacement.size());
            intervalReplacement.put(replacementVariable, (IntervalTerm) term);
            termList.set(i, replacementVariable);
            didChange = true;
        }
        if (term instanceof FunctionTerm) {
            // Rewrite function terms recursively.
            FunctionTerm rewrittenFunctionTerm = rewriteFunctionTerm((FunctionTerm) term, intervalReplacement);
            termList.set(i, rewrittenFunctionTerm);
            didChange = true;
        }
    }
    if (didChange) {
        Atom rewrittenAtom = atom.withTerms(termList);
        return lit.isNegated() ? rewrittenAtom.toLiteral().negate() : rewrittenAtom.toLiteral();
    }
    return lit;
}
Also used : FunctionTerm(at.ac.tuwien.kr.alpha.api.terms.FunctionTerm) ComparisonAtom(at.ac.tuwien.kr.alpha.api.programs.atoms.ComparisonAtom) IntervalTerm(at.ac.tuwien.kr.alpha.commons.terms.IntervalTerm) ArrayList(java.util.ArrayList) VariableTerm(at.ac.tuwien.kr.alpha.api.terms.VariableTerm) Term(at.ac.tuwien.kr.alpha.api.terms.Term) IntervalTerm(at.ac.tuwien.kr.alpha.commons.terms.IntervalTerm) VariableTerm(at.ac.tuwien.kr.alpha.api.terms.VariableTerm) FunctionTerm(at.ac.tuwien.kr.alpha.api.terms.FunctionTerm) ComparisonLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral) BasicAtom(at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom) Atom(at.ac.tuwien.kr.alpha.api.programs.atoms.Atom) IntervalAtom(at.ac.tuwien.kr.alpha.core.atoms.IntervalAtom) ComparisonAtom(at.ac.tuwien.kr.alpha.api.programs.atoms.ComparisonAtom)

Example 2 with ComparisonLiteral

use of at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral in project Alpha by alpha-asp.

the class AggregateOperatorNormalizationTest method assertAggregateBoundIncremented.

private static void assertAggregateBoundIncremented(Rule<Head> sourceRule, Rule<Head> rewrittenRule) {
    AggregateLiteral sourceAggregate = null;
    for (Literal lit : sourceRule.getBody()) {
        if (lit instanceof AggregateLiteral) {
            sourceAggregate = (AggregateLiteral) lit;
        }
    }
    AggregateLiteral rewrittenAggregate = null;
    ComparisonLiteral addedComparisonLiteral = null;
    for (Literal lit : rewrittenRule.getBody()) {
        if (lit instanceof AggregateLiteral) {
            rewrittenAggregate = (AggregateLiteral) lit;
        } else if (lit instanceof ComparisonLiteral) {
            addedComparisonLiteral = (ComparisonLiteral) lit;
        }
    }
    assertNotNull(addedComparisonLiteral);
    assertEquals(addedComparisonLiteral.getAtom().getTerms().get(0), rewrittenAggregate.getAtom().getLowerBoundTerm());
    Term comparisonRightHandTerm = addedComparisonLiteral.getAtom().getTerms().get(1);
    assertTrue(comparisonRightHandTerm instanceof ArithmeticTerm);
    ArithmeticTerm incrementTerm = (ArithmeticTerm) comparisonRightHandTerm;
    assertEquals(ArithmeticOperator.PLUS, incrementTerm.getOperator());
    assertEquals(Terms.newConstant(1), incrementTerm.getRightOperand());
    Term sourceBound = sourceAggregate.getAtom().getLowerBoundTerm() != null ? sourceAggregate.getAtom().getLowerBoundTerm() : sourceAggregate.getAtom().getUpperBoundTerm();
    assertEquals(sourceBound, incrementTerm.getLeftOperand());
}
Also used : AggregateLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral) Literal(at.ac.tuwien.kr.alpha.api.programs.literals.Literal) ComparisonLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral) AggregateLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral) ArithmeticTerm(at.ac.tuwien.kr.alpha.api.terms.ArithmeticTerm) Term(at.ac.tuwien.kr.alpha.api.terms.Term) ArithmeticTerm(at.ac.tuwien.kr.alpha.api.terms.ArithmeticTerm) ComparisonLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral)

Example 3 with ComparisonLiteral

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

Example 4 with ComparisonLiteral

use of at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral in project Alpha by alpha-asp.

the class MinMaxEncoder method encodeAggregateResult.

@Override
protected ASPCore2Program encodeAggregateResult(AggregateInfo aggregateToEncode) {
    ST encodingTemplate = null;
    if (this.getAggregateFunctionToEncode() == AggregateFunctionSymbol.MAX) {
        encodingTemplate = new ST(MAX_LITERAL_ENCODING);
    } else if (this.getAggregateFunctionToEncode() == AggregateFunctionSymbol.MIN) {
        encodingTemplate = new ST(MIN_LITERAL_ENCODING);
    } else {
        // Note that this should definitely not happen due to the check in the constructor!
        throw new UnsupportedOperationException("Cannot encode anything other than min/max aggregates!");
    }
    String id = aggregateToEncode.getId();
    String resultName = aggregateToEncode.getOutputAtom().getPredicate().getName();
    AggregateAtom atom = aggregateToEncode.getLiteral().getAtom();
    ComparisonOperator cmpOp = atom.getLowerBoundOperator();
    encodingTemplate.add("id", id);
    encodingTemplate.add("aggregate_result", resultName);
    if (cmpOp.equals(ComparisonOperators.EQ)) {
        // Aggregate to encode binds a variable, use appropriate result rule.
        ST resultRuleTemplate = new ST(BINDING_LITERAL_RESULT_RULE);
        resultRuleTemplate.add("agg_func", atom.getAggregateFunction().toString().toLowerCase());
        resultRuleTemplate.add("id", id);
        resultRuleTemplate.add("aggregate_result", resultName);
        return parser.parse(encodingTemplate.render() + resultRuleTemplate.render());
    } else {
        /*
			 * Aggregate encoding needs to compare aggregate value with another variable.
			 * Note that this should also use a string template for the result rule. However,
			 * since we need to compared to a (user-supplied) variable, we have to use a definitely
			 * non-conflicting variable name for the aggregate value, i.e. something prefixed with "_".
			 * Since the ProgramParser doesn't accept this, we need to build the result rule
			 * programmatically as a workaround.
			 *
			 * Result rule stringtemplate for reference:
			 * $aggregate_result$($args$, $cmp_term$) :-
			 * $cmp_term$ $cmp_op$ AGG_VAL,
			 * $id$_$agg_func$_element_tuple($args$, AGG_VAL),
			 * $dependencies;separator=\", \"$."
			 */
        NormalHead resultRuleHead = Heads.newNormalHead(Atoms.newBasicAtom(Predicates.getPredicate(resultName, 2), aggregateToEncode.getAggregateArguments(), atom.getLowerBoundTerm()));
        List<Literal> resultRuleBody = new ArrayList<>();
        VariableTerm aggregateValue = Terms.newVariable("_AGG_VAL");
        ComparisonLiteral aggregateValueComparison = Literals.fromAtom(Atoms.newComparisonAtom(atom.getLowerBoundTerm(), aggregateValue, cmpOp), true);
        Literal aggregateResult = Atoms.newBasicAtom(Predicates.getPredicate(id + "_" + atom.getAggregateFunction().toString().toLowerCase() + "_element_tuple", 2), aggregateToEncode.getAggregateArguments(), aggregateValue).toLiteral();
        resultRuleBody.add(aggregateResult);
        resultRuleBody.add(aggregateValueComparison);
        resultRuleBody.addAll(aggregateToEncode.getDependencies());
        InputProgram.Builder bld = InputProgram.builder(parser.parse(encodingTemplate.render()));
        BasicRule resultRule = new BasicRule(resultRuleHead, resultRuleBody);
        bld.addRule(resultRule);
        return bld.build();
    }
}
Also used : BasicRule(at.ac.tuwien.kr.alpha.core.rules.BasicRule) ST(org.stringtemplate.v4.ST) ComparisonOperator(at.ac.tuwien.kr.alpha.api.ComparisonOperator) ArrayList(java.util.ArrayList) 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) AggregateAtom(at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom) ComparisonLiteral(at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral) InputProgram(at.ac.tuwien.kr.alpha.core.programs.InputProgram)

Example 5 with ComparisonLiteral

use of at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral 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)

Aggregations

ComparisonLiteral (at.ac.tuwien.kr.alpha.api.programs.literals.ComparisonLiteral)5 Literal (at.ac.tuwien.kr.alpha.api.programs.literals.Literal)4 ArrayList (java.util.ArrayList)4 Atom (at.ac.tuwien.kr.alpha.api.programs.atoms.Atom)3 Term (at.ac.tuwien.kr.alpha.api.terms.Term)3 VariableTerm (at.ac.tuwien.kr.alpha.api.terms.VariableTerm)3 BasicAtom (at.ac.tuwien.kr.alpha.api.programs.atoms.BasicAtom)2 NormalHead (at.ac.tuwien.kr.alpha.api.rules.heads.NormalHead)2 Unifier (at.ac.tuwien.kr.alpha.commons.substitutions.Unifier)2 BasicRule (at.ac.tuwien.kr.alpha.core.rules.BasicRule)2 HashSet (java.util.HashSet)2 LinkedHashSet (java.util.LinkedHashSet)2 ComparisonOperator (at.ac.tuwien.kr.alpha.api.ComparisonOperator)1 AggregateAtom (at.ac.tuwien.kr.alpha.api.programs.atoms.AggregateAtom)1 ComparisonAtom (at.ac.tuwien.kr.alpha.api.programs.atoms.ComparisonAtom)1 AggregateLiteral (at.ac.tuwien.kr.alpha.api.programs.literals.AggregateLiteral)1 DisjunctiveHead (at.ac.tuwien.kr.alpha.api.rules.heads.DisjunctiveHead)1 ArithmeticTerm (at.ac.tuwien.kr.alpha.api.terms.ArithmeticTerm)1 FunctionTerm (at.ac.tuwien.kr.alpha.api.terms.FunctionTerm)1 IntervalTerm (at.ac.tuwien.kr.alpha.commons.terms.IntervalTerm)1