All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.ikm.reasoner.hybrid.SubsumptionNormalFormBuilder Maven / Gradle / Ivy

The newest version!
package dev.ikm.reasoner.hybrid;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Stream;
import java.util.stream.Collectors;

import org.semanticweb.owlapi.model.AxiomType;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLAxiom;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLClassAxiom;
import org.semanticweb.owlapi.model.OWLClassExpression;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.semanticweb.owlapi.model.OWLEquivalentClassesAxiom;
import org.semanticweb.owlapi.model.OWLObjectIntersectionOf;
import org.semanticweb.owlapi.model.OWLObjectProperty;
import org.semanticweb.owlapi.model.OWLObjectPropertyExpression;
import org.semanticweb.owlapi.model.OWLObjectSomeValuesFrom;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLProperty;
import org.semanticweb.owlapi.model.OWLSubClassOfAxiom;
import org.semanticweb.owlapi.model.OWLSubPropertyChainOfAxiom;
import org.semanticweb.owlapi.model.OWLTransitiveObjectPropertyAxiom;
import org.semanticweb.owlapi.reasoner.OWLReasoner;

public class SubsumptionNormalFormBuilder {

	private OWLOntology kernelOntology;
	private OWLReasoner kernelOwlReasoner;
	private OWLOntology statementOntology;
	private OWLReasoner statementOwlReasoner;
	private HybridReasonerProperties properties;
	
	private HybridSubsumptionTester subsumptionTester;

	private List concepts = new ArrayList<>();
	private HashMap chained = new HashMap<>();
	private HashSet transitive = new HashSet<>();
	private HashMap> superProps = new HashMap<>();
	private HashMap> unmergedSubsumptionNormalFormsSHIELD = new HashMap<>();
	private HashMap subsumptionNormalFormsSHIELD = new HashMap<>();

	private int countNormalized = 0;

	public List getConcepts() {
		return concepts;
	}

	public List getUnmergedSubsumptionNormalFormsSHIELD(OWLClass con) {
		return unmergedSubsumptionNormalFormsSHIELD.get(con);
	}

	public HashMap getSubsumptionNormalFormsSHIELD() {
		return subsumptionNormalFormsSHIELD;
	}

	public SubsumptionNormalForm getSNF(OWLClass con) {
		return subsumptionNormalFormsSHIELD.get(con);
	}

	public SubsumptionNormalFormBuilder(OWLOntology kernelOntology, OWLReasoner kernelOwlReasoner,
			OWLOntology statementOntology, OWLReasoner statementOwlReasoner, HybridReasonerProperties properties) {
		super();
		this.kernelOntology = kernelOntology;
		this.kernelOwlReasoner = kernelOwlReasoner;
		this.statementOntology = statementOntology;
		this.statementOwlReasoner = statementOwlReasoner;
		this.properties = properties;
		this.subsumptionTester = new HybridSubsumptionTester(kernelOntology, properties.temporalAnnotationOwlIri());
	}

// This method was for debugging only
//	public void testSubsumptionsPairwise() {
//		        for (Map.Entry entry : subsumptionNormalFormsSHIELD.entrySet()) {
//		            OWLClass key = entry.getKey();
//		            SubsumptionNormalFormSHIELD value = entry.getValue();
//// DEBUG		            System.out.println("SNF Key=" + key + ", \nSNF Value=\n" + value);
//		        }
////		CustomSubsumptionTesterSHIELD subsumptionTester = new CustomSubsumptionTesterSHIELD();
//		for (OWLClass superConcept : statementOntology.getClassesInSignature()) {
//			for (OWLClass subConcept : statementOntology.getClassesInSignature()) {
//				if (StatementClassifierSHIELD.logicallyDefinedInOntology(superConcept, statementOntology) &&
//					StatementClassifierSHIELD.logicallyDefinedInOntology(subConcept, statementOntology)) {
//
////  "if" statement select a particular concept or pair of concepts to check subsumption with respect to.	
////  If the statement is omitted, this will test subsumption with respect to all pairs of SNFs
//					if (superConcept.getIRI().toString()
//  .contains("#ABSENT_History-of-Allergic-Asthma-in-Patient-in-Past") &&
//	subConcept.getIRI().toString()
//  .contains("#ABSENT_Respiratory-Disease-in-Patient-in-Past")	)  	{
//
//						SubsumptionNormalFormSHIELD superSNF = subsumptionNormalFormsSHIELD.get(superConcept);
//						SubsumptionNormalFormSHIELD subSNF = subsumptionNormalFormsSHIELD.get(subConcept);
//
//// DEBUG						System.out.println("Super Class: " + superConcept);
//// DEBUG						System.out.println(superSNF.toString());
//// DEBUG				System.out.println("Sub Class: " + subConcept);
//// DEBUG						System.out.println(subSNF.toString());
//						boolean isSnfSubsumedBy = subsumptionTester.isSubsumedBy(subSNF, superSNF, kernelOwlReasoner, statementOwlReasoner);
//// DEBUG						System.out.println("     Is Subsumed: " + isSnfSubsumedBy);	
//// DEBUG						System.out.println();
//	}
//				}
//			}
//		}
//	}

	public void init() {
//ReasonerExplorer.pause("about to initialize concepts");
		initConcepts();
//ReasonerExplorer.pause("about to initialize roles");
		initRoles();
		for (OWLAxiom ax : statementOntology.getAxioms()) {
//			if( ax.getAxiomType().getName().equals("Declaration")) {
//				System.out.println("Axiom type name is Declaration!");
//			}
			switch (ax.getAxiomType().getName()) {
			case "Declaration": {
			}
			case "SubClassOf": {
			}
			case "EquivalentClasses": {
			}
			case "SubObjectPropertyOf": {
			}
			case "SubPropertyChainOf": {
			}
			case "TransitiveObjectProperty": {
			}
			case "ReflexiveObjectProperty": {
			}
//  TODO: Not recognizing "Declaration" for some reason and throwing this exception...
			default: {
			} // throw new UnsupportedOperationException("Unexpected Axiom Type: " + ax + "
				// **" + ax.getAxiomType().getName() + "**");
				// TODO: Figure out why this case statement is not recognizing "Declaration"
				// Axioms...
			}
		}
	}

	private void initConcepts() {
// DEBUG		System.out.println("STATEMENT REASONER TAXONOMY - IN SNF BUILDER");
// DEBUG		ReasonerExplorer.printCurrentReasonerTaxonomy((StructuralReasoner) statementOwlReasoner, false);
		for (OWLClass concept : statementOntology.getClassesInSignature()) {
//			NodeSet supers = statementOwlReasoner.getSuperClasses(concept, false);
//			for (Iterator> iterator = supers.iterator(); iterator.hasNext();) {
//				OWLClassNode owlClassNode = (OWLClassNode) iterator.next();
//			}
			concepts.add(concept);
		}
	}

	@SuppressWarnings("unused")
	private void initRoles() {
		for (OWLSubPropertyChainOfAxiom ax : kernelOntology.getAxioms(AxiomType.SUB_PROPERTY_CHAIN_OF)) {
			if (ax.getPropertyChain().size() != 2) {
				throw new UnsupportedOperationException("Unexpected: " + ax);
			}
			OWLObjectProperty prop1 = ax.getPropertyChain().get(0).asOWLObjectProperty();
			OWLObjectProperty prop2 = ax.getPropertyChain().get(1).asOWLObjectProperty();
			OWLObjectProperty sup = ax.getSuperProperty().asOWLObjectProperty();
			if (!prop1.equals(sup)) {
				throw new UnsupportedOperationException("Unexpected: " + ax);
			}
			if (chained.get(prop1) != null) {
				throw new UnsupportedOperationException(
						"Two chains for: " + prop1 + " " + ax + " " + chained.get(prop1));
			}
			chained.put(prop1, prop2);
		}
		for (Entry es : chained.entrySet()) {
		}
		for (OWLTransitiveObjectPropertyAxiom ax : kernelOntology.getAxioms(AxiomType.TRANSITIVE_OBJECT_PROPERTY)) {
			OWLObjectProperty prop = ax.getProperty().asOWLObjectProperty();
			transitive.add(prop);
		}
		for (OWLObjectProperty prop : transitive) {
// LOG			LOG.info("Transitive: " + prop);
		}
		for (Iterator iterator = concepts.iterator(); iterator.hasNext();) {
			OWLClass owlClass = (OWLClass) iterator.next();
		}
		Set allObjectProperties = kernelOntology.getObjectPropertiesInSignature();
		for (Iterator iterator = allObjectProperties.iterator(); iterator.hasNext();) {
			OWLObjectProperty prop = (OWLObjectProperty) iterator.next();
//		for (OWLObjectProperty prop : kernelOntology.getObjectPropertiesInSignature()) {
			superProps.put(prop, new HashSet<>());
			superProps.get(prop).add(prop);
			// TODO Why does this this cause incompleteness warnings
			// TODO: Elk does not support getSuperObjectProperties method! So, commented
			// out.
			/******
			 * superProps of every property will be empty set; later figure out how to
			 * handle them, given above Set propsSuperProps =
			 * kernelReasoner.getSuperObjectProperties(prop, false).getFlattened(); for
			 * (Iterator iterator2 = propsSuperProps.iterator(); iterator2.hasNext();) {
			 * OWLObjectPropertyExpression superProp = (OWLObjectPropertyExpression)
			 * iterator2 .next(); if (!superProp.isOWLTopObjectProperty()) {
			 * superProps.get(prop).add(superProp.asOWLObjectProperty()); } }
			 *******/

		}
		for (Entry> es : superProps.entrySet()) {
			if (es.getValue().size() > 1) {
// LOG				LOG.info("Super props: " + es.getKey());
				for (OWLObjectProperty prop : es.getValue()) {
					if (!prop.equals(es.getKey())) {
// LOG						LOG.info("\t" + prop);
					}
				}
			}
		}
	}

	public void generate() { // was public void generate(Roles roles)
// Needed??		Reasoner.processingSubsumptionNormalFormSHIELD = true;

//ReasonerExplorer.pause("about to generate subsumptionNormalizedConcepts");

		for (OWLClass concept : concepts) {
			for (OWLClassAxiom axiom : getLogicalAxioms(concept, statementOntology)) {
				unmergedSubsumptionNormalFormsSHIELD.put(concept, new ArrayList<>());
				SubsumptionNormalForm expr = createExpression(concept, axiom);
				unmergedSubsumptionNormalFormsSHIELD.get(concept).add(expr);
// DEBUG System.out.println("Initial SNF for " + concept + " is :");
// DEBUG System.out.println(" " + expr.toString());
				simplify(expr.getUngroupedProps());
			}
			if (!getLogicalAxioms(concept, statementOntology).isEmpty()) {
				subsumptionNormalFormsSHIELD.put(concept, mergeNNFs(unmergedSubsumptionNormalFormsSHIELD.get(concept)));
// DEBUG System.out.println("Simplified/Merged SNF for " + concept + " is :");
// DEBUG System.out.println(" " + subsumptionNormalFormSHIELD.get(concept));
			}

			if (++countNormalized % 50 == 0)
				System.out.println("Normalized " + countNormalized);

		}
// Needed??	Reasoner.processingSubsumptionNormalFormSHIELD = false;
	}

	private SubsumptionNormalForm mergeNNFs(List nnfs) {
		SubsumptionNormalForm merged_nnf = new SubsumptionNormalForm();
		// TODO subClassOf
		merged_nnf.setUngroupedProps(new HashSet<>());
		merged_nnf.setFocusConcepts(new HashSet<>());
		for (SubsumptionNormalForm nnf : nnfs) {
			merged_nnf.getUngroupedProps().addAll(nnf.getUngroupedProps());
			merged_nnf.getFocusConcepts().addAll(nnf.getFocusConcepts());
		}
		simplify(merged_nnf.getUngroupedProps());
		simplifyFocusConcepts(merged_nnf.getFocusConcepts());
		if (isAbsentConcept(merged_nnf))
			merged_nnf.setIsAbsent(true);
		else
			merged_nnf.setIsAbsent(false);
		return merged_nnf;
	}

	private OWLClassExpression getDefinition(OWLClass concept, OWLClassAxiom axiom) {
// DEBUG	  System.out.println("The Axiom: " + axiom);
// DEBUG	  System.out.println("The Concept: " + concept);
//		switch (axiom) {
//			case OWLEquivalentClassesAxiom  {
		if (axiom instanceof OWLEquivalentClassesAxiom) {
			Set class_exprs = ((OWLEquivalentClassesAxiom) axiom).getClassExpressions();
			if (class_exprs.size() != 2)
				throw new UnsupportedOperationException("Unexpected: " + class_exprs.size() + " " + class_exprs);
			Iterator iterator = class_exprs.iterator();
			@SuppressWarnings("unused") // Only included to get to 2nd item
			OWLClassExpression clazz = iterator.next();
			OWLClassExpression def = iterator.next();
			return def;
		}
//			case OWLSubClassOfAxiom x -> {
		else if (axiom instanceof OWLSubClassOfAxiom) {
			OWLClassExpression def = ((OWLSubClassOfAxiom) axiom).getSuperClass();
			return def;
		}
//			default -> throw new UnsupportedOperationException("Unexpected: " + axiom.getAxiomType());
		else {
			throw new UnsupportedOperationException("Unexpected: " + axiom.getAxiomType());
		}
	}

	private SubsumptionNormalForm createExpression(OWLClass concept, OWLClassAxiom axiom) {
		SubsumptionNormalForm expr = new SubsumptionNormalForm();
		{
//			switch (axiom) {
//			case OWLEquivalentClassesAxiom x -> expr.setSubClassOf(false);
			if (axiom instanceof OWLEquivalentClassesAxiom)
				expr.setSubClassOf(false);
//				case OWLSubClassOfAxiom x -> expr.setSubClassOf(true);
			else if (axiom instanceof OWLSubClassOfAxiom)
				expr.setSubClassOf(false);
//				default -> throw new UnsupportedOperationException("Unexpected: " + axiom.getAxiomType());
			else
				throw new UnsupportedOperationException("Unexpected: " + axiom.getAxiomType());
//			}
		}
		Set focusConcepts = processDefinitionFocusConcepts(concept, axiom);
		expr.setFocusConcepts(focusConcepts);
		Set roles = processDefinitionProperties(concept, axiom);
		;
		expr.setUngroupedProps(roles);
		return expr;
	}

	@SuppressWarnings("deprecation")
	private Set processDefinitionProperties(OWLClass concept, OWLClassAxiom axiom) {
		Set properties = new HashSet<>();
		OWLClassExpression classDefinition = getDefinition(concept, axiom);
//		switch (axiom) {  // Just a safety check
//			case OWLSubClassOfAxiom x -> { }
//			case OWLEquivalentClassesAxiom x -> { }
//			default -> throw new UnsupportedOperationException("Unexpected Axiom Type: " + axiom.getAxiomType());
		if (axiom instanceof OWLSubClassOfAxiom) {
		} else if (axiom instanceof OWLEquivalentClassesAxiom) {
		} else {
			throw new UnsupportedOperationException("Unexpected Axiom Type: " + axiom.getAxiomType());
		}
//		switch (classDefinition) {
//			case OWLClass y -> {
		if (classDefinition instanceof OWLClass) {
			for (OWLClassAxiom superAxiom : statementOntology.getAxioms((OWLClass) classDefinition)) {
				properties.addAll(processDefinitionProperties(getDefinedClass(superAxiom), superAxiom));
			}
		}
//			case OWLObjectSomeValuesFrom y -> { 
		else if (classDefinition instanceof OWLObjectSomeValuesFrom) {
			properties.add((OWLObjectSomeValuesFrom) classDefinition);
		}
//			case OWLObjectIntersectionOf y -> {
		else if (classDefinition instanceof OWLObjectIntersectionOf) {
			OWLObjectIntersectionOf y = (OWLObjectIntersectionOf) classDefinition;
			properties.addAll(processIntersectionProperties(y.getOperands(), axiom));
		}
//			default -> throw new UnsupportedOperationException(
		else {
			throw new UnsupportedOperationException(
					"Unexpected: " + classDefinition + " " + classDefinition.getClassExpressionType());
		}
		return properties;
	}

	@SuppressWarnings("deprecation")
	private Set processIntersectionProperties(Set class_exprs,
			OWLClassAxiom axiom) {
		Set properties = new HashSet<>();
		for (Iterator iterator = class_exprs.iterator(); iterator.hasNext();) {
			OWLClassExpression class_expr = (OWLClassExpression) iterator.next();
//			switch (class_expr) {
//				case OWLClass z -> {
			if (class_expr instanceof OWLClass) {
				for (OWLClassAxiom superAxiom : statementOntology.getAxioms((OWLClass) class_expr)) {
					properties.addAll(processDefinitionProperties(getDefinedClass(superAxiom), superAxiom));
				}
			}
//				case OWLObjectSomeValuesFrom z -> {
			else if (class_expr instanceof OWLObjectSomeValuesFrom) {
				properties.add((OWLObjectSomeValuesFrom) class_expr);
			}
//				default -> throw new UnsupportedOperationException(
			else {
				throw new UnsupportedOperationException(
						"Unexpected: " + class_expr + " " + class_expr.getClassExpressionType());
				// TODO: This method will not handle intersections within intersections; needed?
				// Would need to recurse to do that
			}
		}
		return properties;
	}

	@SuppressWarnings("deprecation")
	private Set processDefinitionFocusConcepts(OWLClass concept, OWLClassAxiom axiom) {
		Set focusConcepts = new HashSet<>();
		OWLClassExpression classDefinition = getDefinition(concept, axiom);
// DEBUG		if (concept.getIRI().toString().contains("#ABSENT_History-of-Allergic-Asthma-in-Patient-Recently_COPY"))
// DEBUG			System.out.print("");
		{
//			switch (axiom) {
//				case OWLSubClassOfAxiom x -> {
			if (axiom instanceof OWLSubClassOfAxiom) {
				focusConcepts.add(concept); // And don't walk further up the stated hierarchy
			}
//				case OWLEquivalentClassesAxiom x -> {
			else if (axiom instanceof OWLEquivalentClassesAxiom) {
//					switch (classDefinition) {
//						case OWLClass y -> {
				if (classDefinition instanceof OWLClass) {
//							for (OWLClassAxiom superAxiom : statementOntology.getAxioms(classDefinition)) {
					for (OWLClassAxiom superAxiom : statementOntology.getAxioms((OWLClass) classDefinition)) {
						focusConcepts.addAll(processDefinitionFocusConcepts(getDefinedClass(superAxiom), superAxiom));
						return focusConcepts;
					}
				}
//						case OWLObjectSomeValuesFrom y -> { 
				else if (classDefinition instanceof OWLObjectSomeValuesFrom) {
					// ignore this type of expression; ; return null Set
				}
//						case OWLObjectIntersectionOf y -> {
				else if (classDefinition instanceof OWLObjectIntersectionOf) {
					OWLObjectIntersectionOf y = (OWLObjectIntersectionOf) classDefinition;
					focusConcepts = processIntersectionFocusConcepts(y.getOperands(), axiom);
					return focusConcepts;
				}
//						default -> throw new UnsupportedOperationException(
				else {
					throw new UnsupportedOperationException(
							"Unexpected: " + classDefinition + " " + classDefinition.getClassExpressionType());
				}
			}
//				default -> throw new UnsupportedOperationException("Unexpected: " + axiom.getAxiomType());
			else {
				throw new UnsupportedOperationException("Unexpected: " + axiom.getAxiomType());
			}
		}
		return focusConcepts;
	}

	@SuppressWarnings("deprecation")
	private Set processIntersectionFocusConcepts(Set class_exprs, OWLClassAxiom axiom) {
		Set focusConcepts = new HashSet<>();
		for (OWLClassExpression class_expr : class_exprs) {
//			switch (axiom) {
//				case OWLSubClassOfAxiom x -> {
			if (axiom instanceof OWLSubClassOfAxiom) {
//					switch (class_expr) {
//						case OWLClass z -> {
				if (class_expr instanceof OWLClass) {
					focusConcepts.add((OWLClass) class_expr); // Don't walk further up the stated hierarchy
					return focusConcepts;
				}
//						case OWLObjectSomeValuesFrom z -> {
				else if (class_expr instanceof OWLObjectSomeValuesFrom) {
					// Ignore; add no focus concepts
				}
//						default -> throw new UnsupportedOperationException(
				else {
					throw new UnsupportedOperationException(
							"Unexpected: " + class_expr + " " + class_expr.getClassExpressionType());
					// TODO: This method will not handle intersections within intersections; would
					// need to recurse
				}
			}
//				case OWLEquivalentClassesAxiom x -> {
			else if (axiom instanceof OWLEquivalentClassesAxiom) {
//					switch (class_expr) {
//						case OWLClass z -> {
				if (class_expr instanceof OWLClass) {
					OWLClass z = (OWLClass) class_expr;
					for (OWLClassAxiom superAxiom : statementOntology.getAxioms(z)) {
						focusConcepts.addAll(processDefinitionFocusConcepts(getDefinedClass(superAxiom), superAxiom));
						return focusConcepts;
					}
				}
//						case OWLObjectSomeValuesFrom z -> {
				else if (class_expr instanceof OWLObjectSomeValuesFrom) {
					// Ignore; add no focus concepts
				}
//						default -> throw new UnsupportedOperationException(
				else {
					throw new UnsupportedOperationException(
							"Unexpected: " + class_expr + " " + class_expr.getClassExpressionType());
					// TODO: This method will not handle intersections within intersections; would
					// need to recurse
				}
			}
//				default -> throw new UnsupportedOperationException("Unexpected: " + axiom.getAxiomType());
			else {
				throw new UnsupportedOperationException("Unexpected: " + axiom.getAxiomType());
			}
		}
		return focusConcepts;
	}

	private OWLClass getDefinedClass(OWLClassAxiom axiom) {
//		switch (axiom) {
//		case OWLEquivalentClassesAxiom x -> {
//			Set class_exprs = x.getClassExpressions();
		if (axiom instanceof OWLEquivalentClassesAxiom) {
			Set class_exprs = ((OWLEquivalentClassesAxiom) axiom).getClassExpressions();
			if (class_exprs.size() != 2)
				throw new UnsupportedOperationException("Unexpected: " + class_exprs.size() + " " + class_exprs);
			OWLClassExpression definedClass = class_exprs.iterator().next();
			return (OWLClass) definedClass;
		}
//		case OWLSubClassOfAxiom x -> {
//			OWLClassExpression definedClass = x.getSubClass();
		else if (axiom instanceof OWLSubClassOfAxiom) {
			OWLClassExpression definedClass = ((OWLSubClassOfAxiom) axiom).getSubClass();
			return (OWLClass) definedClass;
		}
//		default -> throw new UnsupportedOperationException("Unexpected: " + axiom.getAxiomType());
		else {
			throw new UnsupportedOperationException("Unexpected: " + axiom.getAxiomType());
		}
	}

// Only needed to handle subsumption w.r.t. chained properties for purposes of creating the SNF
// TODO:  CustomSubsumptionTesterSHIELD does not support subsumption w.r.t. chained properties.  Should we add?
	@SuppressWarnings("unused")
	private boolean isSubClassOfEntailed(OWLObjectSomeValuesFrom prop1, OWLObjectSomeValuesFrom prop2) {
		boolean isSubClassOf = false;
		if (superProps.get(prop1.getProperty().asOWLObjectProperty())
				.contains(prop2.getProperty().asOWLObjectProperty())) {
			if (chained.get(prop1.getProperty()) == null && chained.get(prop2.getProperty()) == null
					&& !transitive.contains(prop1.getProperty()) && !transitive.contains(prop2.getProperty())) {
				OWLClass con1 = prop1.getFiller().asOWLClass();
				OWLClass con2 = prop2.getFiller().asOWLClass();
				isSubClassOf = con1.equals(con2) || subsumptionTester.isSubsumedBy(con1, con2, kernelOwlReasoner);
			} else {
			}
		}
		return isSubClassOf;
	}

// This subclass is only needed to handle chained properties.  Currently not handled by classification process
// TODO:  Determine if we need to add support for subsumption w.r.t. chained properties to CustomSubsumptionTesterSHIELD
	private static class SVF {
		private OWLObjectProperty prop;
		private OWLClassExpression filler;

		public SVF(OWLObjectProperty prop, OWLClassExpression filler) {
			super();
			this.prop = prop;
			this.filler = filler;
		}

		@Override
		public int hashCode() {
			return Objects.hash(filler, prop);
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			SVF other = (SVF) obj;
			return Objects.equals(filler, other.filler) && Objects.equals(prop, other.prop);
		}

		@Override
		public String toString() {
			return "SVF(" + prop + " " + filler + ")";
		}

	}

	@SuppressWarnings("unused")
	private HashSet expandChain(OWLObjectProperty prop, OWLClass filler) {
		HashSet svfs = new HashSet<>();
		svfs.add(new SVF(prop, filler));
		while (true) {
			ArrayList svfs_l = new ArrayList<>(svfs);
			for (SVF svf : svfs_l) {
				List chain_exps = expandChain1(svf);
				svfs.addAll(chain_exps);
				List prop_exps = expandSuperProps(svf);
				svfs.addAll(prop_exps);
			}
			if (svfs.size() == svfs_l.size())
				break;
		}
		return svfs;
	}

	private List expandChain1(SVF svf) {
		ArrayList chained_props = new ArrayList<>();
		if (chained.get(svf.prop) != null) {
			chained_props.add(chained.get(svf.prop));
		}
		if (transitive.contains(svf.prop))
			chained_props.add(svf.prop);
//		List chained_cons = subsumptionNormalFormsSHIELD.get(svf.filler).getUngroupedProps().stream()
//				.filter(x -> chained_props.contains(x.getProperty().asOWLObjectProperty()))
//				.map(x -> x.getFiller().asOWLClass()).distinct().toList();
		Stream chained_cons_stream = subsumptionNormalFormsSHIELD.get(svf.filler).getUngroupedProps().stream()
				.filter(x -> chained_props.contains(x.getProperty().asOWLObjectProperty()))
				.map(x -> x.getFiller().asOWLClass()).distinct();
		List chained_cons = chained_cons_stream.collect(Collectors.toList());
//		return chained_cons.stream().map(x -> new SVF(svf.prop, x)).toList();
		return chained_cons.stream().map(x -> new SVF(svf.prop, x)).collect(Collectors.toList());
	}

	private List expandSuperProps(SVF svf) {
//		return superProps.get(svf.prop).stream().filter(x -> !x.equals(svf.prop)).map(x -> new SVF(x, svf.filler))
//				.toList();
		Stream superPropsStream = (Stream) superProps.get(svf.prop).stream().filter(x -> !x.equals(svf.prop))
				.map(x -> new SVF(x, svf.filler));
		return superPropsStream.collect(Collectors.toList());
	}

	@SuppressWarnings("unused")
	private boolean isSubsumedBy(SVF svf1, SVF svf2, OWLReasoner owlReasoner) {
		return subsumptionTester.isSubsumedBy(svf1.prop, svf2.prop)
				&& isSubsumedBy(svf1.filler, svf2.filler, owlReasoner);
	}

	private boolean isSubsumedBy(OWLClassExpression expr1, OWLClassExpression expr2, OWLReasoner owlReasoner) {
		return subsumptionTester.isSubsumedBy(expr1, expr2, owlReasoner);
	}

	private void simplifyFocusConcepts(Set cons) {
		if (cons.isEmpty())
			return;
		ArrayList to_remove = new ArrayList<>();
		for (OWLClass con1 : cons) {
			for (OWLClass con2 : cons) {
				if (con1 == con2)
					continue;
				if (subsumptionTester.isSubsumedBy(con1, con2, statementOwlReasoner)) {
					to_remove.add(con2);
				}
			}
		}
		cons.removeAll(to_remove);
	}

	private void simplify(Set props) {
		if (props.isEmpty())
			return;
		ArrayList to_remove = new ArrayList<>();
		for (OWLObjectSomeValuesFrom prop1 : props) {
			for (OWLObjectSomeValuesFrom prop2 : props) {
// DEBUG	System.out.println("Prop1: " + prop1);
// DEBUG	System.out.println("Prop2: " + prop2);
				if (prop1 == prop2)
					continue;
				if (subsumptionTester.isSubsumedBy(prop1, prop2, kernelOwlReasoner))
					to_remove.add(prop2);
			}
		}
		props.removeAll(to_remove);
	}

	/**
	 * SPECIFIED MODELING OF AN 'ABSENT' CONCEPT: The SubsumptionNormalForm of the
	 * concept has the 'ObjectSomeValuesFrom' constraint defined by
	 * 'createAbsentSomeValuesFrom()';
	 */
	private boolean isAbsentConcept(SubsumptionNormalForm merged_nnf) {
//		OWLObjectSomeValuesFrom absentProperty = createAbsentProperty();
		OWLObjectSomeValuesFrom absentProperty = createAbsentSomeValuesFrom();
//		if (merged_nnf.getUngroupedProps().contains(absentProperty))
		if (containsAbsentProperty(merged_nnf.getUngroupedProps(), absentProperty))
			return true;
		else
			return false;
	}

//	ROLE_GROUP_PROPERTY_NAMESPACE = "http://www.hhs.fda.org/shield/SWEC-Ontology#";
//	public static final String ROLE_GROUP_PROPERTY_NAME)

	private boolean containsAbsentProperty(Set ungroupedProps,
			OWLObjectSomeValuesFrom absentProperty) {
		// Test if absentProperty is among top-level class expressions
		if (ungroupedProps.contains(absentProperty))
			return true;
		// Test if absentProperty is among intersection of class expressions within a
		// top-level role group
		IRI roleGroupPropertyIri = IRI.create(properties.roleGroupProperty());
		for (OWLObjectSomeValuesFrom prop : ungroupedProps) {
			if (prop.getProperty().getNamedProperty().getIRI().equals(roleGroupPropertyIri)) {
				OWLClassExpression propertyValue = prop.getFiller();
				if (propertyValue instanceof OWLObjectSomeValuesFrom) {
					if (((OWLObjectSomeValuesFrom) propertyValue).equals(absentProperty))
						return true;
				} else if (propertyValue instanceof OWLObjectIntersectionOf) {
					Set intersectedClassExpressions = ((OWLObjectIntersectionOf) propertyValue)
							.getOperands();
					for (OWLClassExpression classExpression : intersectedClassExpressions) {
						if (classExpression instanceof OWLObjectSomeValuesFrom)
							if (((OWLObjectSomeValuesFrom) classExpression).equals(absentProperty))
								return true;
					}
				} else {
					// throw exception; filler of role group must either be a single
					// OWLObjectSomeValuesFrom
					// constraint or an intersection of OWLObjectSomeValuesFrom constraints
					throw new RuntimeException("Error:  Filler of the Role-Group property "
							+ roleGroupPropertyIri.toString()
							+ " must be either an OWLObjectSomeValuesFrom or an OWLObjectIntersectionOf object");

				}
			}
		}
		return false;
	};

	/**
	 * Specifies the ObjectSomeValuesFrom constraint that defines an 'absent'
	 * concept in the input OWL ontology. For example, the following parameter
	 * values for this method:
	 * 
	 * absenceNamespace = "http://www.hhs.fda.org/shield/SWEC-Ontology"
	 * absenceProperty = "Situation-Presence" absenceValueNamesapce =
	 * "http://www.hhs.fda.org/shield/SWEC-Ontology" absenceValueName = "Absent"
	 * 
	 * would specify that the following ObjectSomeValuesFrom constraint defines an
	 * 'absent' concept (i.e., a concept is an 'absent' concept if and only if it
	 * has the following ObjectSomeValuesFrom constraint):
	 * 
	 *  
	 * 
	 */
	private OWLObjectSomeValuesFrom createAbsentSomeValuesFrom() {
		OWLDataFactory factory = statementOntology.getOWLOntologyManager().getOWLDataFactory();
		IRI absentValueIri = IRI.create(properties.absenceValue());
		OWLClass absentValueClass = factory.getOWLClass(absentValueIri);
		IRI situationPresencePropertyIri = IRI.create(properties.absenceProperty());
		OWLProperty situationPresenceProperty = factory.getOWLObjectProperty(situationPresencePropertyIri);
		OWLObjectSomeValuesFrom situationAbsentRole = factory.getOWLObjectSomeValuesFrom(
				(OWLObjectPropertyExpression) situationPresenceProperty, (OWLClassExpression) absentValueClass);
		return situationAbsentRole;
	}

	@SuppressWarnings("deprecation")
	public Set getLogicalAxioms(OWLClass concept, OWLOntology statementOntology) {
		Set logicalAxioms = new HashSet();
		for (OWLClassAxiom axiom : statementOntology.getAxioms(concept)) {
			if (axiom.isLogicalAxiom()) {
				logicalAxioms.add(axiom);
			}
		}
		return logicalAxioms;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy