Skip to content

WIP: axiom jenga #207

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
231 changes: 231 additions & 0 deletions OWLTools-Core/src/main/java/owltools/reasoner/AxiomJenga.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
package owltools.reasoner;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;
import org.semanticweb.owlapi.model.AxiomType;
import org.semanticweb.owlapi.model.OWLAxiom;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLClassExpression;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.semanticweb.owlapi.model.OWLEquivalentClassesAxiom;
import org.semanticweb.owlapi.model.OWLObjectPropertyExpression;
import org.semanticweb.owlapi.model.OWLObjectSomeValuesFrom;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyCreationException;
import org.semanticweb.owlapi.model.OWLOntologyManager;
import org.semanticweb.owlapi.model.OWLSubClassOfAxiom;
import org.semanticweb.owlapi.reasoner.OWLReasoner;
import org.semanticweb.owlapi.util.InferredAxiomGenerator;
import org.semanticweb.owlapi.util.InferredOntologyGenerator;
import org.semanticweb.owlapi.util.InferredSubClassAxiomGenerator;

/**
* Utility for abductive reasoning
*
* @author cjm
*
*/
public class AxiomJenga {

private static final Logger LOG = Logger.getLogger(AxiomJenga.class);

public static JengaTower makeJengaTower(OWLOntology ontology, OWLReasoner reasoner) throws OWLOntologyCreationException {
return makeJengaTower(ontology, reasoner, false);
}

public static JengaTower makeJengaTower(OWLOntology ontology, OWLReasoner reasoner,
boolean isReplaceRedundant) throws OWLOntologyCreationException {

Map<OWLAxiom, Integer> axiomJengaScoreMap = new HashMap<>();
OWLOntologyManager manager = ontology.getOWLOntologyManager();
OWLDataFactory dataFactory = manager.getOWLDataFactory();
List<InferredAxiomGenerator<? extends OWLAxiom>> gens =
new ArrayList<InferredAxiomGenerator<? extends OWLAxiom>>();

// TODO
gens.add(new InferredSubClassAxiomGenerator());
InferredOntologyGenerator generator =
new InferredOntologyGenerator(reasoner, gens);
LOG.info("Using these axiom generators:");
for (InferredAxiomGenerator inf: generator.getAxiomGenerators()) {
LOG.info(" " + inf);
}
OWLOntology newAxiomOntology;
newAxiomOntology = manager.createOntology();
generator.fillOntology(dataFactory, newAxiomOntology);

Set<OWLAxiom> entailedAxioms = newAxiomOntology.getAxioms();
Set<OWLAxiom> redundantAxioms = new HashSet<>();

OWLAxiom axiomWithMaxJenga = null;
int maxJengaScore = 0;
int totJengaScore = 0;
int totEquivJengaScore = 0;
int n = 0;
int nEquiv = 0;
int tot = ontology.getLogicalAxioms().size();
for (OWLAxiom axiom : ontology.getLogicalAxioms()) {
n++;
if (n % 100 == 1) {
LOG.info("Axiom "+n+"/"+tot);
}
manager.removeAxiom(ontology, axiom);
reasoner.flush();
newAxiomOntology = manager.createOntology();
generator.fillOntology(dataFactory, newAxiomOntology);
Set<OWLAxiom> entailedAxiomsX = newAxiomOntology.getAxioms();
Set<OWLAxiom> unjustifiedAxioms = new HashSet<>();
for (OWLAxiom ea : entailedAxioms) {
if (!entailedAxiomsX.contains(ea)) {
unjustifiedAxioms.add(ea);
}
}
int s = unjustifiedAxioms.size();
axiomJengaScoreMap.put(axiom, s);
if (s > maxJengaScore) {
maxJengaScore = s;
axiomWithMaxJenga = axiom;
}
if (s == 0) {
redundantAxioms.add(axiom);
}
totJengaScore += s;

if (axiom instanceof OWLEquivalentClassesAxiom) {
nEquiv ++;
totEquivJengaScore += s;
}

// put it back, if it is either non-redundant or we choose to do this
if (s > 0 || isReplaceRedundant) {
manager.addAxiom(ontology, axiom);
}
}
JengaTower jt = new JengaTower();
jt.axiomJengaScoreMap = axiomJengaScoreMap;
List<OWLAxiom> aa = new ArrayList<>(axiomJengaScoreMap.keySet());
aa.sort( (OWLAxiom a1, OWLAxiom a2) ->
axiomJengaScoreMap.get(a1) - axiomJengaScoreMap.get(a2) );
jt.sortedAxioms = aa;
jt.maxJenga = maxJengaScore;
jt.redundantAxioms = redundantAxioms;
jt.axiomWithMaxJenga = axiomWithMaxJenga;
jt.avgJenga = totJengaScore/((double)n);
if (nEquiv > 0)
jt.avgEquivJenga = totEquivJengaScore/((double)nEquiv);
for (OWLAxiom a : aa) {
int s = axiomJengaScoreMap.get(a);
if (s > 1) {
LOG.info(a+" SCORE: " + s);
}
}

return jt;
}

public static JengaTower makeJengaTowerNEW(OWLOntology ontology, OWLReasoner reasoner,
boolean isReplaceRedundant) throws OWLOntologyCreationException {

Map<OWLAxiom, Integer> axiomJengaScoreMap = new HashMap<>();
OWLOntologyManager manager = ontology.getOWLOntologyManager();
OWLDataFactory dataFactory = manager.getOWLDataFactory();
List<InferredAxiomGenerator<? extends OWLAxiom>> gens =
new ArrayList<InferredAxiomGenerator<? extends OWLAxiom>>();

// TODO
gens.add(new InferredSubClassAxiomGenerator());
InferredOntologyGenerator generator =
new InferredOntologyGenerator(reasoner, gens);
LOG.info("Using these axiom generators:");
for (InferredAxiomGenerator inf: generator.getAxiomGenerators()) {
LOG.info(" " + inf);
}
OWLOntology newAxiomOntology;
newAxiomOntology = manager.createOntology();
generator.fillOntology(dataFactory, newAxiomOntology);

Set<OWLAxiom> entailedAxioms = newAxiomOntology.getAxioms();
Set<OWLAxiom> redundantAxioms = new HashSet<>();

OWLAxiom axiomWithMaxJenga = null;
int maxJengaScore = 0;
int totJengaScore = 0;
int totEquivJengaScore = 0;
int n = 0;
int nEquiv = 0;
int tot = ontology.getLogicalAxioms().size();
for (OWLAxiom axiom : ontology.getLogicalAxioms()) {
n++;
if (n % 100 == 1) {
LOG.info("Axiom "+n+"/"+tot);
}
manager.removeAxiom(ontology, axiom);
reasoner.flush();
reasoner.isEntailed(axiom);
if (axiom instanceof OWLSubClassOfAxiom) {
OWLSubClassOfAxiom sca = (OWLSubClassOfAxiom)axiom;
reasoner.getSuperClasses(sca.getSubClass(), false);
}
newAxiomOntology = manager.createOntology();
generator.fillOntology(dataFactory, newAxiomOntology);
Set<OWLAxiom> entailedAxiomsX = newAxiomOntology.getAxioms();
Set<OWLAxiom> unjustifiedAxioms = new HashSet<>();
for (OWLAxiom ea : entailedAxioms) {
if (!entailedAxiomsX.contains(ea)) {
unjustifiedAxioms.add(ea);
}
}
int s = unjustifiedAxioms.size();
axiomJengaScoreMap.put(axiom, s);
if (s > maxJengaScore) {
maxJengaScore = s;
axiomWithMaxJenga = axiom;
}
if (s == 0) {
redundantAxioms.add(axiom);
}
totJengaScore += s;

if (axiom instanceof OWLEquivalentClassesAxiom) {
nEquiv ++;
totEquivJengaScore += s;
}

// put it back, if it is either non-redundant or we choose to do this
if (s > 0 || isReplaceRedundant) {
manager.addAxiom(ontology, axiom);
}
}
JengaTower jt = new JengaTower();
jt.axiomJengaScoreMap = axiomJengaScoreMap;
List<OWLAxiom> aa = new ArrayList<>(axiomJengaScoreMap.keySet());
aa.sort( (OWLAxiom a1, OWLAxiom a2) ->
axiomJengaScoreMap.get(a1) - axiomJengaScoreMap.get(a2) );
jt.sortedAxioms = aa;
jt.maxJenga = maxJengaScore;
jt.redundantAxioms = redundantAxioms;
jt.axiomWithMaxJenga = axiomWithMaxJenga;
jt.avgJenga = totJengaScore/((double)n);
if (nEquiv > 0)
jt.avgEquivJenga = totEquivJengaScore/((double)nEquiv);
for (OWLAxiom a : aa) {
int s = axiomJengaScoreMap.get(a);
if (s > 1) {
LOG.info(a+" SCORE: " + s);
}
}

return jt;
}

public boolean isEntailed(OWLAxiom axiom, OWLReasoner reasoner) {
return false;

}
}
35 changes: 35 additions & 0 deletions OWLTools-Core/src/main/java/owltools/reasoner/JengaTower.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package owltools.reasoner;

import java.util.List;
import java.util.Map;
import java.util.Set;

import org.semanticweb.owlapi.model.OWLAxiom;

public class JengaTower {
public Map<OWLAxiom, Integer> axiomJengaScoreMap;
public List<OWLAxiom> sortedAxioms;
public Integer maxJenga;
public OWLAxiom axiomWithMaxJenga;
public Double avgJenga = 0.0;
public Double avgEquivJenga = 0.0;
public Set<OWLAxiom> redundantAxioms;

public JengaTower() {
}

/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "JengaTower [axiomJengaScoreMap=" + axiomJengaScoreMap.size()
+ ", sortedAxioms=" + sortedAxioms.size() + ", maxJenga=" + maxJenga
+ ", redundantAxioms=" + redundantAxioms.size()
+ " " + axiomWithMaxJenga
+ ", avgJenga=" + avgJenga + ", avgEquivJenga=" + avgEquivJenga
+ "]";
}


}
54 changes: 54 additions & 0 deletions OWLTools-Core/src/test/resources/jenga.obo
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
[Term]
id: X:1
equivalent_to: Y:1

[Term]
id: X:2
is_a: X:1
equivalent_to: Y:2

[Term]
id: X:3
is_a: X:2
equivalent_to: Y:3

[Term]
id: X:4
is_a: X:3
equivalent_to: Y:4


[Term]
id: Y:1
equivalent_to: Z:1

[Term]
id: Y:2
is_a: Y:1
equivalent_to: Z:2

[Term]
id: Y:3
is_a: Y:2
equivalent_to: Z:3

[Term]
id: Y:4
is_a: Y:3
equivalent_to: Z:4


[Term]
id: Z:1

[Term]
id: Z:2
is_a: Z:1

[Term]
id: Z:3
is_a: Z:2

[Term]
id: Z:4
is_a: Z:3
69 changes: 69 additions & 0 deletions OWLTools-Core/src/test/resources/jenga_ld.obo
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
[Term]
id: G:1

[Term]
id: GY:1

[Term]
id: X:1
intersection_of: G:1
intersection_of: part_of Y:1

[Term]
id: X:2
is_a: X:1
intersection_of: G:1
intersection_of: part_of Y:2

[Term]
id: X:3
is_a: X:2
intersection_of: G:1
intersection_of: part_of Y:3

[Term]
id: X:4
is_a: X:3
intersection_of: G:1
intersection_of: part_of Y:4

[Term]
id: Y:1
intersection_of: GY:1
intersection_of: part_of Z:1

[Term]
id: Y:2
is_a: Y:1
intersection_of: GY:1
intersection_of: part_of Z:2

[Term]
id: Y:3
is_a: Y:2
intersection_of: GY:1
intersection_of: part_of Z:3

[Term]
id: Y:4
is_a: Y:3
intersection_of: GY:1
intersection_of: part_of Z:4

[Term]
id: Z:1

[Term]
id: Z:2
is_a: Z:1

[Term]
id: Z:3
is_a: Z:2

[Term]
id: Z:4
is_a: Z:3

[Typedef]
id: part_of