use of at.ac.tuwien.kr.alpha.api.terms.ArithmeticTerm in project Alpha by alpha-asp.
the class ArithmeticTermsRewriting method rewriteArithmeticSubterms.
private Term rewriteArithmeticSubterms(Term term, List<Literal> bodyLiterals) {
// Keep term as-is if it contains no ArithmeticTerm.
if (!containsArithmeticTerm(term)) {
return term;
}
// Switch on term type.
if (term instanceof ArithmeticTerm) {
VariableTerm replacementVariable = Terms.newVariable(ARITHMETIC_VARIABLES_PREFIX + numArithmeticVariables++);
bodyLiterals.add(Atoms.newComparisonAtom(replacementVariable, term, ComparisonOperators.EQ).toLiteral());
return replacementVariable;
} else if (term instanceof VariableTerm || term instanceof ConstantTerm) {
return term;
} else if (term instanceof FunctionTerm) {
List<Term> termList = ((FunctionTerm) term).getTerms();
List<Term> rewrittenTermList = new ArrayList<>();
for (Term subterm : termList) {
rewrittenTermList.add(rewriteArithmeticSubterms(subterm, bodyLiterals));
}
return Terms.newFunctionTerm(((FunctionTerm) term).getSymbol(), rewrittenTermList);
} else {
throw Util.oops("Rewriting unknown Term type: " + term.getClass());
}
}
use of at.ac.tuwien.kr.alpha.api.terms.ArithmeticTerm in project Alpha by alpha-asp.
the class Unification method unifyTerms.
private static boolean unifyTerms(Term left, Term right, Unifier currentSubstitution, boolean keepLeftAsIs) {
final Term leftSubs = left.substitute(currentSubstitution);
final Term rightSubs = right.substitute(currentSubstitution);
if (leftSubs == rightSubs) {
return true;
}
if (!keepLeftAsIs && leftSubs instanceof VariableTerm && !currentSubstitution.isVariableSet((VariableTerm) leftSubs)) {
currentSubstitution.put((VariableTerm) leftSubs, rightSubs);
return true;
}
if (rightSubs instanceof VariableTerm && !currentSubstitution.isVariableSet((VariableTerm) rightSubs)) {
currentSubstitution.put((VariableTerm) rightSubs, leftSubs);
return true;
}
if (leftSubs instanceof FunctionTerm && rightSubs instanceof FunctionTerm) {
final FunctionTerm leftFunction = (FunctionTerm) leftSubs;
final FunctionTerm rightFunction = (FunctionTerm) rightSubs;
if (!leftFunction.getSymbol().equals(rightFunction.getSymbol()) || leftFunction.getTerms().size() != rightFunction.getTerms().size()) {
return false;
}
for (int i = 0; i < leftFunction.getTerms().size(); i++) {
final Term leftTerm = leftFunction.getTerms().get(i);
final Term rightTerm = rightFunction.getTerms().get(i);
if (!unifyTerms(leftTerm, rightTerm, currentSubstitution, keepLeftAsIs)) {
return false;
}
}
return true;
}
if (leftSubs instanceof ArithmeticTerm && rightSubs instanceof ArithmeticTerm) {
// ArithmeticTerms are similar to FunctionTerms, i.e. if the operator is the same and its subterms unify, the ArithmeticTerms unify.
final ArithmeticTerm leftArithmeticTerm = (ArithmeticTerm) leftSubs;
final ArithmeticTerm rightArithmeticTerm = (ArithmeticTerm) rightSubs;
if (!leftArithmeticTerm.getOperator().equals(rightArithmeticTerm.getOperator())) {
return false;
}
final Term leftTermLeftSubterm = leftArithmeticTerm.getLeftOperand();
final Term rightTermLeftSubterm = rightArithmeticTerm.getLeftOperand();
if (!unifyTerms(leftTermLeftSubterm, rightTermLeftSubterm, currentSubstitution, keepLeftAsIs)) {
return false;
}
final Term leftTermRightSubterm = leftArithmeticTerm.getRightOperand();
final Term rightTermRightSubterm = rightArithmeticTerm.getRightOperand();
if (!unifyTerms(leftTermRightSubterm, rightTermRightSubterm, currentSubstitution, keepLeftAsIs)) {
return false;
}
return true;
}
return false;
}
use of at.ac.tuwien.kr.alpha.api.terms.ArithmeticTerm 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());
}
use of at.ac.tuwien.kr.alpha.api.terms.ArithmeticTerm in project Alpha by alpha-asp.
the class ComparisonLiteralImpl method getSatisfyingSubstitutions.
@Override
public List<Substitution> getSatisfyingSubstitutions(Substitution partialSubstitution) {
// Treat case where this is just comparison with all variables bound by partialSubstitution.
final Term left = getAtom().getTerms().get(0).substitute(partialSubstitution);
final Term right = getAtom().getTerms().get(1).substitute(partialSubstitution);
final boolean leftAssigning = assignable(left);
final boolean rightAssigning = assignable(right);
if (!leftAssigning && !rightAssigning) {
// No assignment (variables are bound by partialSubstitution), thus evaluate comparison only.
Term leftEvaluatedSubstitute = evaluateTerm(left);
if (leftEvaluatedSubstitute == null) {
return Collections.emptyList();
}
Term rightEvaluatedSubstitute = evaluateTerm(right);
if (rightEvaluatedSubstitute == null) {
return Collections.emptyList();
}
if (compare(leftEvaluatedSubstitute, rightEvaluatedSubstitute)) {
return Collections.singletonList(partialSubstitution);
} else {
return Collections.emptyList();
}
}
// Treat case that this is X = t or t = X.
VariableTerm variable = null;
Term expression = null;
if (leftAssigning) {
variable = (VariableTerm) left;
expression = right;
}
if (rightAssigning) {
variable = (VariableTerm) right;
expression = left;
}
Term groundTerm = expression.substitute(partialSubstitution);
Term resultTerm = null;
// Check if the groundTerm is an arithmetic expression and evaluate it if so.
if (groundTerm instanceof ArithmeticTerm) {
Integer result = Terms.evaluateGroundTerm(groundTerm);
if (result == null) {
return Collections.emptyList();
}
resultTerm = Terms.newConstant(result);
} else {
// Ground term is another term (constant, or function term).
resultTerm = groundTerm;
}
BasicSubstitution extendedSubstitution = new BasicSubstitution(partialSubstitution);
extendedSubstitution.put(variable, resultTerm);
return Collections.singletonList(extendedSubstitution);
}
Aggregations