uk.ac.manchester.cs.factplusplusad.LowerBoundComplementEvaluator Maven / Gradle / Ivy
package uk.ac.manchester.cs.factplusplusad;
import java.util.Iterator;
import org.semanticweb.owlapi.model.HasOperands;
import org.semanticweb.owlapi.model.OWLDataComplementOf;
import org.semanticweb.owlapi.model.OWLDataHasValue;
import org.semanticweb.owlapi.model.OWLDataIntersectionOf;
import org.semanticweb.owlapi.model.OWLDataOneOf;
import org.semanticweb.owlapi.model.OWLDataUnionOf;
import org.semanticweb.owlapi.model.OWLEntity;
import org.semanticweb.owlapi.model.OWLLiteral;
import org.semanticweb.owlapi.model.OWLObject;
import org.semanticweb.owlapi.model.OWLObjectComplementOf;
import org.semanticweb.owlapi.model.OWLObjectHasSelf;
import org.semanticweb.owlapi.model.OWLObjectHasValue;
import org.semanticweb.owlapi.model.OWLObjectIntersectionOf;
import org.semanticweb.owlapi.model.OWLObjectInverseOf;
import org.semanticweb.owlapi.model.OWLObjectOneOf;
import org.semanticweb.owlapi.model.OWLObjectPropertyExpression;
import org.semanticweb.owlapi.model.OWLObjectUnionOf;
import org.semanticweb.owlapi.model.OWLPropertyExpression;
import org.semanticweb.owlapi.model.OWLPropertyRange;
import org.semanticweb.owlapi.model.OWLSubPropertyChainOfAxiom;
/**
* Determine how many instances can an expression have. All methods return
* maximal n such that expr\in CC^{>= n}, n >= 1
*/
class LowerBoundComplementEvaluator extends CardinalityEvaluatorBase {
LowerBoundComplementEvaluator(Signature s) {
super(s);
}
@Override
int getNoneValue() {
return 0;
}
@Override
int getAllValue() {
return -1;
}
@Override
int getOneNoneLower(boolean v) {
return v ? 1 : getNoneValue();
}
// TODO: checks only C top-locality, not R */
@Override
int getEntityValue(OWLEntity entity) {
if (entity.isTopEntity()) {
return noLowerValue();
}
if ((entity.isOWLObjectProperty() || entity.isOWLDataProperty() || entity.isOWLDatatype())
&& entity
.isBottomEntity()) {
return anyLowerValue();
}
if (entity.isBottomEntity()) {
return 1;
}
return getOneNoneLower(botCLocal() && nc(entity));
}
@Override
int getForallValue(OWLPropertyExpression r, OWLPropertyRange c) {
return getOneNoneLower(isTopEquivalent(r) && isLowerGE(getLowerBoundComplement(c), 1));
}
@Override
int getMinValue(int m, OWLPropertyExpression r, OWLPropertyRange c) {
// m > 0 and...
if (m <= 0) {
return noLowerValue();
}
// R = \bot or...
if (isBotEquivalent(r)) {
return 1;
}
// C \in C^{<= m-1}
return getOneNoneLower(isUpperLT(getUpperBoundDirect(c), m));
}
@Override
int getMaxValue(int m, OWLPropertyExpression r, OWLPropertyRange c) {
// R = \top and...
if (!isTopEquivalent(r)) {
return noLowerValue();
}
// C\in C^{>= m+1}
if (isLowerGT(getLowerBoundDirect(c), m)) {
return m + 1;
} else {
return noLowerValue();
}
}
@Override
int getExactValue(int m, OWLPropertyExpression r, OWLPropertyRange c) {
// here the maximal value between Mix and Max is an answer. The -1
// case will be dealt with automagically
// because both min and max are between 0 and m+1
return Math.max(getMinValue(m, r, c), getMaxValue(m, r, c));
}
int getAndValue(HasOperands expr) {
int max = getNoneValue();
// we are looking for the maximal value here; ANY need to be
// special-cased
Iterator it = expr.operands().iterator();
while (it.hasNext()) {
C p = it.next();
int n = getLowerBoundComplement(p);
if (n == anyLowerValue()) {
return anyLowerValue();
}
max = Math.max(max, n);
}
return max;
}
int getOrValue(HasOperands expr) {
// return m - sumK, where
// true if found a conjunct that is in C^{>=}
boolean foundC = false;
int foundM = 0;
// the m- and k- values for the C_j with max m+k
int mMax = 0, kMax = 0;
// sum of all known k
int sumK = 0;
// 1st pass: check for none-case, deals with deterministic cases
Iterator it = expr.operands().iterator();
while (it.hasNext()) {
C p = it.next();
// C_j \in CC^{>= m}
int m = getLowerBoundComplement(p);
// C_j \in C^{<= k}
int k = getUpperBoundDirect(p);
// note bound flip for K
// case 0: if both aren't known then we don't know
if (m == noLowerValue() && k == noUpperValue()) {
return noLowerValue();
}
// if only k exists then add it to k
if (m == noLowerValue()) {
sumK += k;
continue;
}
// if only m exists then set it to m
if (k == noUpperValue()) {
if (foundC) {
// should not have 2 elements in C
return noLowerValue();
}
foundC = true;
foundM = m;
continue;
}
// here both k and m are values
sumK += k;
// count k for the
if (k + m > kMax + mMax) {
kMax = k;
mMax = m;
}
}
// here we know the best candidate for M, and only need to set it up
if (foundC) {
// found during the deterministic case
foundM -= sumK;
return foundM > 0 ? foundM : noLowerValue();
} else {
// no deterministic option; choose the best one
sumK -= kMax;
mMax -= sumK;
return mMax > 0 ? mMax : noLowerValue();
}
}
// concept expressions
@Override
public void visit(OWLObjectComplementOf expr) {
value = getLowerBoundDirect(expr.getOperand());
}
@Override
public void visit(OWLObjectIntersectionOf expr) {
value = getAndValue(expr);
}
@Override
public void visit(OWLObjectUnionOf expr) {
value = getOrValue(expr);
}
@Override
public void visit(OWLObjectOneOf o) {
value = noLowerValue();
}
@Override
public void visit(OWLObjectHasSelf expr) {
value = getOneNoneLower(isBotEquivalent(expr.getProperty()));
}
@Override
public void visit(OWLObjectHasValue expr) {
value = getOneNoneLower(isBotEquivalent(expr.getProperty()));
}
@Override
public void visit(OWLDataHasValue expr) {
value = getOneNoneLower(isBotEquivalent(expr.getProperty()));
}
// object role expressions
@Override
public void visit(OWLObjectInverseOf expr) {
value = getLowerBoundComplement(expr.getInverseProperty());
}
@Override
public void visit(OWLSubPropertyChainOfAxiom expr) {
for (OWLObjectPropertyExpression p : expr.getPropertyChain()) {
if (isBotEquivalent(p)) {
value = anyLowerValue();
return;
}
}
value = noLowerValue();
}
@Override
public void visit(OWLLiteral o) {
value = 1;
}
@Override
public void visit(OWLDataComplementOf expr) {
value = getLowerBoundDirect(expr.getDataRange());
}
@Override
public void visit(OWLDataIntersectionOf expr) {
value = getAndValue(expr);
}
@Override
public void visit(OWLDataUnionOf expr) {
value = getOrValue(expr);
}
@Override
public void visit(OWLDataOneOf o) {
value = noLowerValue();
}
}