package uk.ac.manchester.cs.jfact.kernel;
/* This file is part of the JFact DL reasoner
Copyright 2011-2013 by Ignazio Palmisano, Dmitry Tsarkov, University of Manchester
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA*/
import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import uk.ac.manchester.cs.jfact.helpers.DLTree;
import conformance.PortedFrom;
/** DLTREE utils */
@PortedFrom(file = "tAxiom.h", name = "InAx")
public class InAx implements Serializable {
private static final long serialVersionUID = 11000L;
/**
* @return an RW concept from a given [C|I]NAME-rooted DLTree
* @param p
* the tree
*/
public static Concept getConcept(DLTree p) {
return (Concept) p.elem().getNE();
}
/**
* @param C
* concept
* @param t
* tbox
* @return true if a concept C is a concept is non-primitive
*/
@PortedFrom(file = "tAxiom.cpp", name = "isNP")
public static boolean isNP(Concept C, TBox t) {
return C.isNonPrimitive() && !hasDefCycle(C);
}
@PortedFrom(file = "tAxiom.cpp", name = "hasDefCycle")
static boolean hasDefCycle(Concept C) {
if (C.isPrimitive()) {
return false;
}
return hasDefCycle(C, new HashSet<Concept>());
}
@PortedFrom(file = "tAxiom.cpp", name = "hasDefCycle")
static boolean hasDefCycle(Concept C, Set<Concept> visited) {
// interested in non-primitive
if (C.isPrimitive()) {
return false;
}
// already seen -- cycle
if (visited.contains(C)) {
return true;
}
// check the structure: looking for the \exists R.C
DLTree p = C.getDescription();
if (!p.isNOT()) {
return false;
}
p = p.getChild();
if (p.token() != Token.FORALL) {
return false;
}
p = p.getRight();
if (!p.isNOT()) {
return false;
}
p = p.getChild();
if (!p.isName()) {
return false;
}
// here P is a concept
// remember C
visited.add(C);
// check p
return hasDefCycle(getConcept(p), visited);
}
/**
* @return true iff P is a TOP
* @param p
* the tree
*/
public static boolean isTop(DLTree p) {
return p.isBOTTOM();
}
/**
* @return true iff P is a BOTTOM
* @param p
* the tree
*/
public static boolean isBot(DLTree p) {
return p.isTOP();
}
/**
* @return true iff P is a positive concept name
* @param p
* the tree
*/
public static boolean isPosCN(DLTree p) {
return p.isNOT() && p.getChild().isName();
}
/**
* @param p
* the tree
* @param t
* tbox
* @return true iff P is a positive non-primitive CN
*/
public static boolean isPosNP(DLTree p, TBox t) {
return isPosCN(p) && isNP(getConcept(p.getChild()), t);
}
/**
* @return true iff P is a positive primitive CN
* @param p
* the tree
*/
public static boolean isPosPC(DLTree p) {
return isPosCN(p) && getConcept(p.getChild()).isPrimitive();
}
/**
* @return true iff P is a negative concept name
* @param p
* the tree
*/
public static boolean isNegCN(DLTree p) {
return p.isName();
}
/**
* @param p
* the tree
* @param t
* tbox
* @return true iff P is a negative non-primitive CN
*/
public static boolean isNegNP(DLTree p, TBox t) {
return isNegCN(p) && isNP(getConcept(p), t);
}
/**
* @return true iff P is a negative primitive CN
* @param p
* the tree
*/
public static boolean isNegPC(DLTree p) {
return isNegCN(p) && getConcept(p).isPrimitive();
}
/**
* @return check whether P is in the form (and C D)
* @param p
* the tree
*/
public static boolean isAnd(DLTree p) {
return p.isNOT() && p.getChild().isAND();
}
/**
* @return true iff P is an OR expression
* @param p
* the tree
*/
public static boolean isOr(DLTree p) {
return p.isAND();
}
/**
* @return true iff P is a general FORALL expression
* @param p
* the tree
*/
public static boolean isForall(DLTree p) {
return p.isNOT() && p.getChild().token() == Token.FORALL;
}
/**
* @return true iff P is an object FORALL expression
* @param p
* the tree
*/
public static boolean isOForall(DLTree p) {
return isForall(p)
&& !Role.resolveRole(p.getChild().getLeft()).isDataRole();
}
/**
* @return true iff P is a FORALL expression suitable for absorption
* @param p
* the tree
*/
public static boolean isAbsForall(DLTree p) {
if (!isOForall(p)) {
return false;
}
DLTree C = p.getChild().getRight();
if (isTop(C)) {
return false;
}
return !C.isName() || !getConcept(C).isSystem();
}
private static final Map<String, Integer> created = new HashMap<String, Integer>();
/**
* @param s
* s
*/
private static void add(String s) {
if (created.containsKey(s)) {
created.put(s, created.get(s) + 1);
} else {
created.put(s, 1);
}
}
/**
* @param s
* s
* @return index for s
*/
private static int get(String s) {
return created.containsKey(s) ? created.get(s) : 0;
}
/** init SAbsRepCN */
public static void SAbsRepCN() {
add("SAbsRepCN");
}
/** init SAbsRepForall */
public static void SAbsRepForall() {
add("SAbsRepForall");
}
/** init SAbsBApply */
public static void SAbsBApply() {
add("SAbsBApply");
}
/** init SAbsSplit */
public static void SAbsSplit() {
add("SAbsSplit");
}
/** init SAbsTApply */
public static void SAbsTApply() {
add("SAbsTApply");
}
/** init SAbsCApply */
public static void SAbsCApply() {
add("SAbsCApply");
}
/** init SAbsCAttempt */
public static void SAbsCAttempt() {
add("SAbsCAttempt");
}
/** init SAbsRApply */
public static void SAbsRApply() {
add("SAbsRApply");
}
/** init SAbsRAttempt */
public static void SAbsRAttempt() {
add("SAbsRAttempt");
}
/** init SAbsInput */
public static void SAbsInput() {
add("SAbsInput");
}
/** init SAbsAction */
public static void SAbsAction() {
add("SAbsAction");
}
/** init SAbsNApply */
public static void SAbsNApply() {
add("SAbsNApply");
}
/** init SAbsNAttempt */
public static void SAbsNAttempt() {
add("SAbsNAttempt");
}
/** @return true if map contains SAbsRepCN */
public static boolean containsSAbsRepCN() {
return created.containsKey("SAbsRepCN");
}
/** @return true if map contains SAbsRepForall */
public static boolean containsSAbsRepForall() {
return created.containsKey("SAbsRepForall");
}
/** @return true if map contains SAbsBApply */
public static boolean containsSAbsBApply() {
return created.containsKey("SAbsBApply");
}
/** @return true if map contains SAbsSplit */
public static boolean containsSAbsSplit() {
return created.containsKey("SAbsSplit");
}
/** @return true if map contains SAbsTApply */
public static boolean containsSAbsTApply() {
return created.containsKey("SAbsTApply");
}
/** @return true if map contains SAbsCApply */
public static boolean containsSAbsCApply() {
return created.containsKey("SAbsCApply");
}
/** @return true if map contains SAbsCAttempt */
public static boolean containsSAbsCAttempt() {
return created.containsKey("SAbsCAttempt");
}
/** @return true if map contains SAbsRApply */
public static boolean containsSAbsRApply() {
return created.containsKey("SAbsRApply");
}
/** @return true if map contains SAbsRAttempt */
public static boolean containsSAbsRAttempt() {
return created.containsKey("SAbsRAttempt");
}
/** @return true if map contains SAbsInput */
public static boolean containsSAbsInput() {
return created.containsKey("SAbsInput");
}
/** @return true if map contains SAbsAction */
public static boolean containsSAbsAction() {
return created.containsKey("SAbsAction");
}
/** @return true if map contains SAbsNApply */
public static boolean containsSAbsNApply() {
return created.containsKey("SAbsNApply");
}
/** @return true if map contains SAbsNAttempt */
public static boolean containsSAbsNAttempt() {
return created.containsKey("SAbsNAttempt");
}
/** @return value for SAbsRepCN */
public static int getSAbsRepCN() {
return get("SAbsRepCN");
}
/** @return value for SAbsRepForall */
public static int getSAbsRepForall() {
return get("SAbsRepForall");
}
/** @return value for SAbsBApply */
public static int getSAbsBApply() {
return get("SAbsBApply");
}
/** @return value for SAbsSplit */
public static int getSAbsSplit() {
return get("SAbsSplit");
}
/** @return value for SAbsTApply */
public static int getSAbsTApply() {
return get("SAbsTApply");
}
/** @return value for SAbsCApply */
public static int getSAbsCApply() {
return get("SAbsCApply");
}
/** @return value for SAbsCAttempt */
public static int getSAbsCAttempt() {
return get("SAbsCAttempt");
}
/** @return value for SAbsRApply */
public static int getSAbsRApply() {
return get("SAbsRApply");
}
/** @return value for SAbsRAttempt */
public static int getSAbsRAttempt() {
return get("SAbsRAttempt");
}
/** @return value for SAbsInput */
public static int getSAbsInput() {
return get("SAbsInput");
}
/** @return value for SAbsAction */
public static int getSAbsAction() {
return get("SAbsAction");
}
/** @return value for SAbsNApply */
public static int getSAbsNApply() {
return get("SAbsNApply");
}
/** @return value for SAbsNAttempt */
public static int getSAbsNAttempt() {
return get("SAbsNAttempt");
}
/**
* @param p
* dltree representing a forall
* @return true iff P is a FORALL expression suitable for absorption with
* name at the end
*/
@PortedFrom(file = "tAxiom.h", name = "isSimpleForall")
public static boolean isSimpleForall(DLTree p) {
if (!isAbsForall(p)) {
return false;
}
DLTree C = p.getChild().getRight();
// forall is simple if its filler is a name of a primitive concept
// XXX check
return C.isName() && getConcept(C).getDescription() == null;
}
}