Commit 78914ed6 authored by Mirko Serbak's avatar Mirko Serbak
Browse files

public release

parent 90fd5813
......@@ -5,7 +5,7 @@
<groupId>chimp</groupId>
<artifactId>chimp.plugin</artifactId>
<version>1.0.2</version>
<version>1.1.0</version>
<packaging>bundle</packaging>
<name>Chimp Plugin</name>
......@@ -17,33 +17,60 @@
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/edu.stanford.protege/protege-editor-owl -->
<dependency>
<groupId>edu.stanford.protege</groupId>
<artifactId>protege-editor-owl</artifactId>
<version>5.0.0</version>
<version>5.5.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.assertj/assertj-core -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.17.0</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.miglayout/miglayout -->
<dependency>
<groupId>com.miglayout</groupId>
<artifactId>miglayout</artifactId>
<version>3.7.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.scilab.forge/jlatexmath -->
<dependency>
<groupId>org.scilab.forge</groupId>
<artifactId>jlatexmath</artifactId>
<version>1.0.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sourceforge.owlapi/org.semanticweb.hermit -->
<dependency>
<groupId>net.sourceforge.owlapi</groupId>
<artifactId>org.semanticweb.hermit</artifactId>
<version>1.3.8.413</version>
<type>bundle</type>
<version>1.4.5.456</version>
<!-- CHANGE TO TEST TO EXCLUDE IT FROM TARGET -->
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.knowm.xchart/xchart -->
<dependency>
<groupId>org.scilab.forge</groupId>
<artifactId>jlatexmath</artifactId>
<version>1.0.7</version>
<groupId>org.knowm.xchart</groupId>
<artifactId>xchart</artifactId>
<version>3.6.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-csv -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.8</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
......@@ -66,6 +93,17 @@
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<excludes>
<!-- Exclude performance tests-->
<exclude>**/*PerformanceTest.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
......@@ -80,7 +118,8 @@
<Embed-Dependency>
miglayout; version="3.7.4"; scope=compile|runtime,
jlatexmath; version="1.0.7"; scope=compile|runtime
jlatexmath; version="1.0.7"; scope=compile|runtime,
xchart; version="3.6.5"; scope=compile|runtime,
</Embed-Dependency>
<Import-Package>
org.protege.editor.owl.*;version="5.0.0", <!-- equivalent to [5.0.0,infinity) -->
......
package metrics;
import org.semanticweb.owlapi.model.OWLAxiom;
import java.util.Set;
public interface ImpactMetric {
/**
* This interface acts as a marker interface and enforces the following method:
* <p>
* calculateMetricWithMaterializations() is used for testing purposes: see test/metrictests/ontologies
*/
double calculateMetricWithMaterializations(Set<OWLAxiom> oldMaterialization, Set<OWLAxiom> newMaterialization);
}
......@@ -6,8 +6,7 @@ public abstract class Metric {
private final String displayName;
private final String description;
private String latexFormula;
private Number value;
private final LinkedList<Number> oldValues = new LinkedList<>();
private final LinkedList<Number> values = new LinkedList<>();
public Metric(String displayName, String description) {
this.displayName = displayName;
......@@ -22,18 +21,11 @@ public abstract class Metric {
public abstract void calculateMetric();
public void updateMetric(Number newValue) {
if (getValue() != null) {
addOldValue(getValue());
}
setValue(newValue);
}
private void setValue(Number value) {
this.value = value;
addValue(newValue);
}
private void addOldValue(Number oldValue) {
oldValues.add(oldValue);
private void addValue(Number oldValue) {
values.add(oldValue);
}
public String getDisplayName() {
......@@ -49,20 +41,19 @@ public abstract class Metric {
}
public Number getValue() {
return value;
return values.isEmpty() ? null : values.getLast();
}
public Number getFirstOldValue() {
return oldValues.isEmpty() ? null : oldValues.getFirst();
public LinkedList<Number> getValues() {
return values;
}
public Number getLastOldValue() {
return oldValues.isEmpty() ? null : oldValues.getLast();
public Number getFirstValue() {
return values.isEmpty() ? null : values.getFirst();
}
//TODO check if this function can be avoided
public boolean hasMultipleOldNonzeroValues() {
return oldValues.size() > 1 && oldValues.stream().anyMatch(x -> x.doubleValue() != 0);
public Number getPreviousValue() {
return values.size() > 1 ? values.get(values.size() - 2) : null;
}
private Double getChangeDifference(Number oldValue, Number newValue) {
......@@ -89,15 +80,9 @@ public abstract class Metric {
public Double getLastChange(boolean absolute, boolean cumulative) {
if (absolute) {
return cumulative ? getChangeDifference(getFirstOldValue(), getValue()) : getChangeDifference(getLastOldValue(), getValue());
return cumulative ? getChangeDifference(getFirstValue(), getValue()) : getChangeDifference(getPreviousValue(), getValue());
} else {
return cumulative ? getChangePercentage(getFirstOldValue(), getValue()) : getChangePercentage(getLastOldValue(), getValue());
return cumulative ? getChangePercentage(getFirstValue(), getValue()) : getChangePercentage(getPreviousValue(), getValue());
}
}
public String toString() {
return getDisplayName() + ", value: " + getValue() +
", old values: " + oldValues +
(getLastChange(true, false) != null ? ", difference: " + getLastChange(true, false) : "");
}
}
package metrics;
public interface PrimitiveMetric {
}
package metrics;
public interface RatioMetric {
}
package metrics.impact;
import metrics.ImpactMetric;
import metrics.Metric;
import org.semanticweb.owlapi.model.*;
import org.semanticweb.owlapi.reasoner.OWLReasoner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reasoning.ChimpReasoner;
import java.util.Set;
public class GraphDistanceImpact extends Metric implements ImpactMetric {
private final Logger log = LoggerFactory.getLogger(GraphDistanceImpact.class);
private final ChimpReasoner chimpReasoner;
private final OWLReasoner underlyingReasoner;
private Double I_M_old;
public GraphDistanceImpact(ChimpReasoner chimpReasoner) {
super("Graph Distance Impact",
"This measure is an abstract comparison of the graph comparison " +
"of the materializations. It signals distance between the " +
"two materializations, meaning, the closer the number is to " +
"1 the further apart ar the two mateiralizations. The " +
"topoligical index zero-th order Randic index is used within " +
"the graph distance, wich represents the structure of the graph " +
"using degree.",
"1 - e^-{(\\frac{I(M_i) - I(M_{i+1})}{2})^2}");
this.chimpReasoner = chimpReasoner;
underlyingReasoner = chimpReasoner.getUnderlyingReasoner();
}
@Override
public void calculateMetric() {
Set<OWLAxiom> currentMaterialization = chimpReasoner.getCurrentMaterialization();
Set<OWLAxiom> firstMaterialization = chimpReasoner.getFirstMaterialization();
if (currentMaterialization != null) {
updateMetric(calculateMetricWithMaterializations(firstMaterialization, currentMaterialization));
} else {
log.debug(getDisplayName() + " could not be calculated because there were no previous materializations");
}
}
@Override
public double calculateMetricWithMaterializations(Set<OWLAxiom> oldMaterialization, Set<OWLAxiom> newMaterialization) {
if (I_M_old == null) {
I_M_old = getI_M(oldMaterialization);
}
double I_M_new = getI_M(newMaterialization);
int rho = newMaterialization.size() - oldMaterialization.size();
double index = (I_M_old - I_M_new) / rho;
double exponent = Math.pow(index, 2.0);
return 1 - Math.exp(-exponent);
}
public double getI_M(Set<OWLAxiom> materialization) {
int I_M = 0;
for (OWLAxiom axiom : materialization) {
I_M += 1.0 / Math.sqrt(getHierarchyDegree(axiom));
}
return I_M;
}
public int getHierarchyDegree(OWLAxiom axiom) {
int degree = 0;
for (OWLEntity entity : axiom.getSignature()) {
if (entity.isOWLDataProperty()) {
degree += underlyingReasoner.getSubDataProperties((OWLDataProperty) entity, true).getFlattened().size() +
underlyingReasoner.getSuperDataProperties((OWLDataProperty) entity, true).getFlattened().size();
}
if (entity.isOWLClass()) {
degree += underlyingReasoner.getSubClasses((OWLClass) entity, true).getFlattened().size() +
underlyingReasoner.getSuperClasses((OWLClass) entity, true).getFlattened().size();
}
if (entity.isOWLObjectProperty()) {
degree += underlyingReasoner.getSubObjectProperties((OWLObjectProperty) entity, true).getFlattened().size() +
underlyingReasoner.getSuperObjectProperties((OWLObjectProperty) entity, true).getFlattened().size();
}
}
return degree;
}
}
package metrics.primitive;
import metrics.Metric;
import metrics.PrimitiveMetric;
import org.semanticweb.owlapi.model.OWLOntology;
public class NumberOfAnnotations extends Metric {
private final OWLOntology ontology;
import java.util.Set;
import java.util.stream.Collectors;
public NumberOfAnnotations(OWLOntology ontology) {
public class NumberOfAnnotations extends Metric implements PrimitiveMetric {
private final Set<OWLOntology> ontologies;
public NumberOfAnnotations(Set<OWLOntology> ontologies) {
super("Number of Annotations", "Counts the number of annotations in the ontology.");
this.ontology = ontology;
this.ontologies = ontologies;
}
@Override
public void calculateMetric() {
updateMetric(ontology.getAnnotations().size());
updateMetric(ontologies.stream()
.flatMap(o -> o.getAnnotations().stream())
.collect(Collectors.toSet())
.size()
);
}
}
package metrics.primitive;
import metrics.Metric;
import metrics.PrimitiveMetric;
import org.semanticweb.owlapi.model.OWLOntology;
public class NumberOfClasses extends Metric {
private final OWLOntology ontology;
import java.util.Set;
import java.util.stream.Collectors;
public NumberOfClasses(OWLOntology ontology) {
public class NumberOfClasses extends Metric implements PrimitiveMetric {
private final Set<OWLOntology> ontologies;
public NumberOfClasses(Set<OWLOntology> ontologies) {
super("Number of Classes", "Counts the number of classes in the ontology signature.");
this.ontology = ontology;
this.ontologies = ontologies;
}
@Override
public void calculateMetric() {
updateMetric(ontology.getClassesInSignature().size());
updateMetric(ontologies.stream()
.flatMap(o -> o.getClassesInSignature().stream())
.collect(Collectors.toSet())
.size()
);
}
}
package metrics.primitive;
import metrics.Metric;
import metrics.PrimitiveMetric;
import org.semanticweb.owlapi.model.OWLOntology;
public class NumberOfDatatypeProperties extends Metric {
private final OWLOntology ontology;
import java.util.Set;
import java.util.stream.Collectors;
public NumberOfDatatypeProperties(OWLOntology ontology) {
public class NumberOfDatatypeProperties extends Metric implements PrimitiveMetric {
private final Set<OWLOntology> ontologies;
public NumberOfDatatypeProperties(Set<OWLOntology> ontologies) {
super("Number of Datatype Properties", "Counts the number of datatype properties in the ontology signature.");
this.ontology = ontology;
this.ontologies = ontologies;
}
@Override
public void calculateMetric() {
updateMetric(ontology.getDataPropertiesInSignature().size());
updateMetric(ontologies.stream()
.flatMap(o -> o.getDataPropertiesInSignature().stream())
.collect(Collectors.toSet())
.size()
);
}
}
package metrics.primitive;
import metrics.Metric;
import metrics.PrimitiveMetric;
import org.semanticweb.owlapi.model.AxiomType;
import org.semanticweb.owlapi.model.OWLOntology;
public class NumberOfEquivalentClassRelations extends Metric {
private final OWLOntology ontology;
import java.util.Set;
import java.util.stream.Collectors;
public NumberOfEquivalentClassRelations(OWLOntology ontology) {
public class NumberOfEquivalentClassRelations extends Metric implements PrimitiveMetric {
private final Set<OWLOntology> ontologies;
public NumberOfEquivalentClassRelations(Set<OWLOntology> ontologies) {
super("Number of Equivalent Class Relations", "Counts the number of 'equivClass' relations in the ontology.");
this.ontology = ontology;
this.ontologies = ontologies;
}
@Override
public void calculateMetric() {
updateMetric(ontology.getAxioms(AxiomType.EQUIVALENT_CLASSES).size());
updateMetric(ontologies.stream()
.flatMap(o -> o.getAxioms(AxiomType.EQUIVALENT_CLASSES).stream())
.collect(Collectors.toSet())
.size()
);
}
}
package metrics.primitive;
import metrics.Metric;
import metrics.PrimitiveMetric;
import org.semanticweb.owlapi.model.OWLOntology;
public class NumberOfIndividuals extends Metric {
private final OWLOntology ontology;
import java.util.Set;
import java.util.stream.Collectors;
public NumberOfIndividuals(OWLOntology ontology) {
public class NumberOfIndividuals extends Metric implements PrimitiveMetric {
private final Set<OWLOntology> ontologies;
public NumberOfIndividuals(Set<OWLOntology> ontologies) {
super("Number of Individuals", "Counts the number of individuals / instances in the ontology.");
this.ontology = ontology;
this.ontologies = ontologies;
}
@Override
public void calculateMetric() {
updateMetric(ontology.getIndividualsInSignature().size());
updateMetric(ontologies.stream()
.flatMap(o -> o.getIndividualsInSignature().stream())
.collect(Collectors.toSet())
.size()
);
}
}
package metrics.primitive;
import metrics.Metric;
import metrics.PrimitiveMetric;
import org.semanticweb.owlapi.model.AxiomType;
import org.semanticweb.owlapi.model.OWLOntology;
public class NumberOfInheritanceRelations extends Metric {
private final OWLOntology ontology;
import java.util.Set;
import java.util.stream.Collectors;
public NumberOfInheritanceRelations(OWLOntology ontology) {
public class NumberOfInheritanceRelations extends Metric implements PrimitiveMetric {
private final Set<OWLOntology> ontologies;
public NumberOfInheritanceRelations(Set<OWLOntology> ontologies) {
super("Number of Inheritance Relations", "Counts the number of 'subClassOf' relations in the ontology.");
this.ontology = ontology;
this.ontologies = ontologies;
}
@Override
public void calculateMetric() {
updateMetric(ontology.getAxioms(AxiomType.SUBCLASS_OF).size());
updateMetric(ontologies.stream()
.flatMap(o -> o.getAxioms(AxiomType.SUBCLASS_OF).stream())
.collect(Collectors.toSet())
.size()
);
}
}
package metrics.primitive;
import metrics.Metric;
import metrics.PrimitiveMetric;
import org.semanticweb.owlapi.model.AxiomType;
import org.semanticweb.owlapi.model.OWLOntology;
public class NumberOfInverseRelations extends Metric {
private final OWLOntology ontology;
import java.util.Set;
import java.util.stream.Collectors;
public NumberOfInverseRelations(OWLOntology ontology) {
public class NumberOfInverseRelations extends Metric implements PrimitiveMetric {
private final Set<OWLOntology> ontologies;
public NumberOfInverseRelations(Set<OWLOntology> ontologies) {
super("Number of Inverse Relations", "Counts the number of 'inverseOf' relations in the ontology.");
this.ontology = ontology;
this.ontologies = ontologies;
}
@Override
public void calculateMetric() {
int inverseFunctionalObjectProperties = ontology.getAxioms(AxiomType.INVERSE_FUNCTIONAL_OBJECT_PROPERTY).size();
int inverseObjectProperties = ontology.getAxioms(AxiomType.INVERSE_OBJECT_PROPERTIES).size();
int inverseFunctionalObjectProperties = ontologies.stream()
.flatMap(o -> o.getAxioms(AxiomType.INVERSE_FUNCTIONAL_OBJECT_PROPERTY).stream())
.collect(Collectors.toSet())
.size();
int inverseObjectProperties = ontologies.stream()
.flatMap(o -> o.getAxioms(AxiomType.INVERSE_OBJECT_PROPERTIES).stream())
.collect(Collectors.toSet())
.size();
updateMetric(inverseFunctionalObjectProperties + inverseObjectProperties);
}
}
package metrics.primitive;
import metrics.Metric;
import metrics.PrimitiveMetric;
import org.semanticweb.owlapi.model.OWLOntology;
public class NumberOfObjectProperties extends Metric {
private final OWLOntology ontology;
import java.util.Set;
import java.util.stream.Collectors;
public NumberOfObjectProperties(OWLOntology ontology) {
public class NumberOfObjectProperties extends Metric implements PrimitiveMetric {
private final Set<OWLOntology> ontologies;
public NumberOfObjectProperties(Set<OWLOntology> ontologies) {
super("Number of Object Properties", "Counts the number of object properties in the ontology signature.");
this.ontology = ontology;
this.ontologies = ontologies;
}
@Override
public void calculateMetric() {
updateMetric(ontology.getObjectPropertiesInSignature().size());
updateMetric(ontologies.stream()
.flatMap(o -> o.getObjectPropertiesInSignature().stream())
.collect(Collectors.toSet())
.size()
);
}
}
package metrics.primitive;
import metrics.Metric;
import metrics.PrimitiveMetric;
import org.semanticweb.owlapi.model.OWLOntology;
public class NumberOfProperties extends Metric {
private final OWLOntology ontology;
import java.util.Set;
public class NumberOfProperties extends Metric implements PrimitiveMetric {
NumberOfObjectProperties numberOfObjectPropertiesMetric;
NumberOfDatatypeProperties numberOfDatatypePropertiesMetric;
public NumberOfProperties(OWLOntology ontology) {
public NumberOfProperties(Set<OWLOntology> ontologies) {
super("Number of Properties",
"Counts the total number of properties in the ontology signature. " +
"This is equivalent to the sum of the datatype properties and the object properties.");
this.ontology = ontology;
this.numberOfObjectPropertiesMetric = new NumberOfObjectProperties(ontology);
this.numberOfDatatypePropertiesMetric = new NumberOfDatatypeProperties(ontology);
this.numberOfObjectPropertiesMetric = new NumberOfObjectProperties(ontologies);