use of at.ac.tuwien.kr.alpha.api.terms.FunctionTerm 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.FunctionTerm 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;
}
use of at.ac.tuwien.kr.alpha.api.terms.FunctionTerm in project Alpha by alpha-asp.
the class SubstitutionTest method specializeTermsFunctionTermBinding.
@Test
public void specializeTermsFunctionTermBinding() {
Substitution substitution = new BasicSubstitution();
substitution.put(Y, A);
FunctionTerm groundFunctionTerm = Terms.newFunctionTerm("f", B, C);
Instance qfBC = new Instance(groundFunctionTerm);
Term nongroundFunctionTerm = Terms.newFunctionTerm("f", B, X);
BasicAtom qfBX = Atoms.newBasicAtom(Predicates.getPredicate("q", 1), nongroundFunctionTerm);
Substitution substitution1 = BasicSubstitution.specializeSubstitution(qfBX, qfBC, substitution);
assertEquals(C, substitution1.eval(X));
assertEquals(A, substitution1.eval(Y));
}
use of at.ac.tuwien.kr.alpha.api.terms.FunctionTerm 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.FunctionTerm in project Alpha by alpha-asp.
the class FactIntervalEvaluator method constructFactInstances.
/**
* Helper to construct Instances from a fact that may contain intervals.
*
* @param fact the fact potentially containing intervals.
* @return all instances stemming from unfolding the intervals.
*/
public static List<Instance> constructFactInstances(Atom fact) {
// Construct instance(s) from the fact.
int arity = fact.getPredicate().getArity();
Term[] currentTerms = new Term[arity];
boolean containsIntervals = false;
// Check if instance contains intervals at all.
for (int i = 0; i < arity; i++) {
Term term = fact.getTerms().get(i);
currentTerms[i] = term;
if (term instanceof IntervalTerm) {
containsIntervals = true;
} else if (term instanceof FunctionTerm && IntervalTerm.functionTermContainsIntervals((FunctionTerm) term)) {
containsIntervals = true;
throw new UnsupportedOperationException("Intervals inside function terms in facts are not supported yet. Try turning the fact into a rule.");
}
}
// If fact contains no intervals, simply return the single instance.
if (!containsIntervals) {
return Collections.singletonList(new Instance(currentTerms));
}
// Fact contains intervals, unroll them all.
return unrollInstances(currentTerms, 0);
}
Aggregations