EquivalenceSetMergeUtil { public void merge() throws IncoherentOntologyException { Set<Node<? extends OWLEntity>> nodes = new HashSet<Node<? extends OWLEntity>>(); Map<OWLEntity, Node<? extends OWLEntity>> nodeByRep = new HashMap<OWLEntity, Node<? extends OWLEntity>>(); Set<OWLClass> badClasses = new HashSet<>(); Set<OWLClass> unsats = reasoner.getUnsatisfiableClasses().getEntitiesMinusBottom(); if (unsats.size() > 0) { throw new IncoherentOntologyException(unsats); } for (OWLClass c : ont.getClassesInSignature()) { Node<OWLClass> n = reasoner.getEquivalentClasses(c); if (n.getSize() > 1) { nodes.add(n); nodeByRep.put(c, n); } } for (OWLNamedIndividual i : ont.getIndividualsInSignature()) { IndividualNodeSetPolicy policy = reasoner.getIndividualNodeSetPolicy(); Node<OWLNamedIndividual> n = reasoner.getSameIndividuals(i); LOG.info("SAME INDS: "+n.getEntities()); if (n.getSize() > 1) { nodes.add(n); nodeByRep.put(i, n); } } LOG.info("TOTAL SETS-OF-SETS (redundant): "+nodeByRep.keySet().size()); OWLAnnotationProperty xrefProperty = graph.getAnnotationProperty(OboFormatTag.TAG_XREF.getTag()); Map<OWLEntity,IRI> e2iri = new HashMap<OWLEntity,IRI>(); Set<OWLEntity> seenClasses = new HashSet<OWLEntity>(); Set <OWLAxiom> newAxiomsNoRewrite = new HashSet<OWLAxiom>(); for (Node<? extends OWLEntity> n : nodes) { boolean isSeen = false; for (OWLEntity c : n.getEntities()) { if (seenClasses.contains(c)) { isSeen = true; break; } seenClasses.add(c); } if (isSeen) { continue; } if (true) { OWLEntity cliqueLeader = null; Double best = null; for (OWLEntity c : n.getEntities()) { Double score = getScore(c, prefixScoreMap); LOG.info(c +" SC: "+score); if (best == null || (score != null && score > best)) { cliqueLeader = c; best = score; } } LOG.info("Clique leader; BEST: "+best+" FOR: "+n.getEntities()); for (OWLEntity c : n.getEntities()) { if (c.equals(cliqueLeader)) continue; LOG.info(c + " --> "+cliqueLeader); e2iri.put(c, cliqueLeader.getIRI()); for (String p : noMergePrefixes) { if (hasPrefix(c,p) && hasPrefix(cliqueLeader,p)) { LOG.error("Illegal merge into "+p+" :: "+owlpp.render(c)+" --> "+ owlpp.render(cliqueLeader)); badClasses.add(c.asOWLClass()); } } if (isAddEquivalenceAxioms) { OWLAxiom eca = null; OWLAnnotationValue value = graph.getDataFactory().getOWLLiteral(graph.getIdentifier(c)); eca = graph.getDataFactory().getOWLAnnotationAssertionAxiom(xrefProperty, cliqueLeader.getIRI(), value); LOG.info("Preserving ECA to represetative: "+eca); newAxiomsNoRewrite.add(eca); } } } if (isRemoveAxiomatizedXRefs) { Set<OWLAxiom> rmXrefAxioms = new HashSet<OWLAxiom>(); for (OWLEntity c : n.getEntities()) { for (OWLAnnotationAssertionAxiom a : graph.getSourceOntology().getAnnotationAssertionAxioms(c.getIRI())) { if (a.getProperty().equals(xrefProperty)) { OWLClass d = null; if (a.getValue() instanceof OWLLiteral) { d = graph.getOWLClassByIdentifier(((OWLLiteral)(a.getValue())).getLiteral()); } else if (a.getValue() instanceof IRI) { d = graph.getOWLClass( (IRI)(a.getValue())); } else { LOG.error("Can't convert: "+a); } if (d != null && !graph.getSourceOntology().getAnnotationAssertionAxioms(d.getIRI()).isEmpty()) { LOG.info("removing xref between two non-dangling classes, "+c+" -> "+d); rmXrefAxioms.add(a); } } } } graph.getManager().removeAxioms(ont, rmXrefAxioms); } for (OWLAnnotationProperty p : propertyPrefixScoreMap.keySet()) { Map<String, Double> pmap = propertyPrefixScoreMap.get(p); OWLEntity representativeForProp = null; Double bestForProp = null; for (OWLEntity c : n.getEntities()) { String v = graph.getAnnotationValue(c, p); if (v == null || v.equals("")) continue; LOG.info(c + " . "+p+" = "+v); Double score = getScore(c, pmap); if (bestForProp == null || (score != null && score > bestForProp)) { representativeForProp = c; bestForProp = score; } } for (OWLEntity c : n.getEntities()) { if (c.equals(representativeForProp)) continue; Set<OWLAxiom> rmAxioms = new HashSet<OWLAxiom>(); for (OWLAnnotationAssertionAxiom ax : ont.getAnnotationAssertionAxioms(c.getIRI())) { if (ax.getProperty().equals(p)) { rmAxioms.add(ax); } } graph.getManager().removeAxioms(ont, rmAxioms); } } } if (!badClasses.isEmpty()) { LOG.error("The following classes would be merged: "+badClasses); throw new IncoherentOntologyException(badClasses); } OWLEntityRenamer oer = new OWLEntityRenamer(graph.getManager(), graph.getAllOntologies()); LOG.info("Mapping "+e2iri.size()+" entities"); List<OWLOntologyChange> changes = oer.changeIRI(e2iri); graph.getManager().applyChanges(changes); LOG.info("Mapped "+e2iri.size()+" entities!"); graph.getManager().addAxioms(ont, newAxiomsNoRewrite); Set<OWLAxiom> rmAxioms = new HashSet<OWLAxiom>(); for (OWLSubClassOfAxiom a : ont.getAxioms(AxiomType.SUBCLASS_OF)) { if (a.getSubClass().equals(a.getSuperClass())) { LOG.info("REFLEXIVE: "+a); rmAxioms.add(a); } } for (OWLEquivalentClassesAxiom a : ont.getAxioms(AxiomType.EQUIVALENT_CLASSES)) { if (a.getClassExpressions().size() < 2) { LOG.info("UNARY: "+a); rmAxioms.add(a); } } for (OWLAnnotationAssertionAxiom a : ont.getAxioms(AxiomType.ANNOTATION_ASSERTION)) { if (a.getProperty().getIRI().equals(IRI.create("http: rmAxioms.add(a); } } if (rmAxioms.size() > 0) { LOG.info("REMOVING AXIOMS: "+rmAxioms.size()); graph.getManager().removeAxioms(ont, rmAxioms); } } EquivalenceSetMergeUtil(OWLGraphWrapper g, OWLReasoner r); void setPropertyPrefixScore(OWLAnnotationProperty p, String prefix, Double score); void setPrefixScore(Map<String, Double> pmap, String prefix,
			Double score); void setPrefixScore(String prefix,
			Double score); void noMergePrefix(String p); void setRemoveAxiomatizedXRefs(boolean isRemoveAxiomatizedXRefs); void setAddEquivalenceAxioms(boolean isAddEquivalenceAxioms); void merge(); public OWLReasoner reasoner; }
@Test public void testMerge() throws OWLOntologyCreationException, IOException, IncoherentOntologyException, OWLOntologyStorageException { ParserWrapper pw = new ParserWrapper(); OWLGraphWrapper g = pw.parseToOWLGraph(getResourceIRIString("equivalence-set-merge-util-test.obo")); OWLOntology ont1 = g.getSourceOntology(); ElkReasonerFactory rf = new ElkReasonerFactory(); OWLReasoner reasoner = rf.createReasoner(ont1); EquivalenceSetMergeUtil esmu = new EquivalenceSetMergeUtil(g, reasoner); esmu.setPrefixScore("A", 8.0); esmu.setPrefixScore("B", 6.0); esmu.setPrefixScore("C", 4.0); OWLAnnotationProperty lp = g.getDataFactory().getOWLAnnotationProperty( OWLRDFVocabulary.RDFS_LABEL.getIRI() ); esmu.setPropertyPrefixScore( lp, "C", 5.0); esmu.setPropertyPrefixScore( lp, "B", 4.0); esmu.setPropertyPrefixScore( lp, "A", 3.0); OWLAnnotationProperty dp = g.getDataFactory().getOWLAnnotationProperty( Obo2OWLVocabulary.IRI_IAO_0000115.getIRI() ); esmu.setPropertyPrefixScore( dp, "B", 5.0); esmu.setPropertyPrefixScore( dp, "A", 4.0); esmu.setPropertyPrefixScore( dp, "C", 3.0); esmu.setRemoveAxiomatizedXRefs(true); esmu.merge(); OWLDocumentFormat fmt = new OBODocumentFormat(); pw.saveOWL(g.getSourceOntology(), "target/esmu.owl"); pw.saveOWL(g.getSourceOntology(), fmt, "target/esmu.obo"); OWLOntology ont2 = pw.parseOWL(getResourceIRIString("equivalence-set-merge-util-expected.obo")); assertEquals(0, compare(ont1, ont2)); }